diff --git a/app/src/main/java/com/odysee/app/MainActivity.java b/app/src/main/java/com/odysee/app/MainActivity.java index d0049d4b..39d8cdd5 100644 --- a/app/src/main/java/com/odysee/app/MainActivity.java +++ b/app/src/main/java/com/odysee/app/MainActivity.java @@ -35,8 +35,10 @@ import android.os.Looper; import android.provider.MediaStore; import android.support.v4.media.session.MediaSessionCompat; +import android.text.Editable; import android.text.Spannable; import android.text.SpannableString; +import android.text.TextWatcher; import android.text.style.TypefaceSpan; import android.util.Base64; import android.util.Log; @@ -418,6 +420,10 @@ public class MainActivity extends AppCompatActivity implements SharedPreferences private ScheduledFuture scheduledWalletUpdater; private boolean walletSyncScheduled; + ScheduledExecutorService searchWorker; + ScheduledFuture scheduledSearchFuture; + private boolean autoSearchEnabled = false; + ChannelCreateDialogFragment channelCreationBottomSheet; AccountManager accountManager; @@ -734,9 +740,72 @@ public void onClick(View view) { findViewById(R.id.fragment_container_search).setVisibility(View.VISIBLE); String query = queryText.getText().toString(); - SearchFragment fragment = (SearchFragment) getSupportFragmentManager().findFragmentByTag("SEARCH"); - currentDisplayFragment = fragment; - fragment.search(query, 0); + SearchFragment searchFragment = (SearchFragment) getSupportFragmentManager().findFragmentByTag("SEARCH"); + + if (searchFragment != null) { + searchFragment.search(query, 0); + } + } + } + }); + + ((EditText)findViewById(R.id.search_query_text)).addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + Context context = getApplicationContext(); + if (context != null) { + SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context); + autoSearchEnabled = sp.getBoolean("com.odysee.app.preference.userinterface.Autosearch", false); + } + if (autoSearchEnabled) { + if (searchWorker == null) { + searchWorker = Executors.newSingleThreadScheduledExecutor(); + } + + // Cancel any previously scheduled search as soon as possible if not yet running. + // Let it finish otherwise, as it will be re-scheduled on aftertextChanged() + if (scheduledSearchFuture != null && !scheduledSearchFuture.isCancelled()) { + scheduledSearchFuture.cancel(false); + } + } + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) { + + } + + @Override + public void afterTextChanged(Editable s) { + if (autoSearchEnabled) { + if (!s.toString().equals("")) { + Runnable runnable = new Runnable() { + public void run() { + runOnUiThread(new Runnable() { + @Override + public void run() { + EditText queryText = findViewById(R.id.search_query_text); + + findViewById(R.id.fragment_container_search).setVisibility(View.VISIBLE); + String query = queryText.getText().toString(); + + SearchFragment searchFragment = (SearchFragment) getSupportFragmentManager().findFragmentByTag("SEARCH"); + + if (searchFragment != null) { + searchFragment.search(query, 0); + } + } + }); + } + }; + scheduledSearchFuture = searchWorker.schedule(runnable, 500, TimeUnit.MILLISECONDS); + } else { + SearchFragment searchFragment = (SearchFragment) getSupportFragmentManager().findFragmentByTag("SEARCH"); + + if (searchFragment != null) { + searchFragment.search("", 0); + } + } } } }); @@ -756,18 +825,22 @@ public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) { @Override public void onClick(View view) { EditText queryText = findViewById(R.id.search_query_text); - InputMethodManager inputMethodManager = (InputMethodManager) queryText.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + InputMethodManager inputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); inputMethodManager.hideSoftInputFromWindow(queryText.getWindowToken(), 0); - getSupportFragmentManager().beginTransaction() - .remove(getSupportFragmentManager().findFragmentByTag("SEARCH")).commit(); + Fragment searchFragment = getSupportFragmentManager().findFragmentByTag("SEARCH"); + if (searchFragment != null) { + getSupportFragmentManager().beginTransaction().remove(searchFragment).commit(); + } + ((EditText)findViewById(R.id.search_query_text)).setText(""); showBottomNavigation(); switchToolbarForSearch(false); // On tablets, multiple fragments could be visible. Don't show Home Screen when File View is visible - if (findViewById(R.id.main_activity_other_fragment).getVisibility() != View.VISIBLE) + if (findViewById(R.id.main_activity_other_fragment).getVisibility() != View.VISIBLE) { findViewById(R.id.fragment_container_main_activity).setVisibility(View.VISIBLE); + } showWalletBalance(); findViewById(R.id.fragment_container_search).setVisibility(View.GONE); @@ -994,6 +1067,14 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { return super.onOptionsItemSelected(item); } + public void cancelScheduledSearchFuture() { + if (scheduledSearchFuture != null && !scheduledSearchFuture.isCancelled()) { + scheduledSearchFuture.cancel(true); + } + if (searchWorker != null && !searchWorker.isShutdown()) { + searchWorker.shutdown(); + } + } public void hideToolbar() { findViewById(R.id.toolbar).setVisibility(View.GONE); } diff --git a/app/src/main/java/com/odysee/app/ui/findcontent/SearchFragment.java b/app/src/main/java/com/odysee/app/ui/findcontent/SearchFragment.java index 0ea1e478..4a934741 100644 --- a/app/src/main/java/com/odysee/app/ui/findcontent/SearchFragment.java +++ b/app/src/main/java/com/odysee/app/ui/findcontent/SearchFragment.java @@ -168,6 +168,7 @@ public void onStop() { if (activity != null) { activity.resetCurrentDisplayFragment(); activity.showBottomNavigation(); + activity.cancelScheduledSearchFuture(); } super.onStop(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1d66fa18..3edf245d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -297,6 +297,7 @@ Continue playing media in the background after closing picture-in-picture mode Autoplay media files Enable dark theme + Perform search while typing Show mature content Show URL suggestions Notifications diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index ea4dc5c6..0863ee6e 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -29,6 +29,12 @@ app:title="@string/enable_dark_mode" app:singleLineTitle="false" app:iconSpaceReserved="false" /> +