Bläddra i källkod

Use rxjava to debounce search instead of custom debouncer

Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
Álvaro Brey 2 år sedan
förälder
incheckning
d1d61e87a9

+ 0 - 2
app/src/main/java/com/nextcloud/talk/api/NcApi.java

@@ -66,7 +66,6 @@ import retrofit2.http.FieldMap;
 import retrofit2.http.FormUrlEncoded;
 import retrofit2.http.GET;
 import retrofit2.http.Header;
-import retrofit2.http.Headers;
 import retrofit2.http.Multipart;
 import retrofit2.http.POST;
 import retrofit2.http.PUT;
@@ -521,7 +520,6 @@ public interface NcApi {
                                               @Url String url,
                                               @Query("reaction") String reaction);
 
-    // TODO use path params instead of passing URL
     @GET
     Observable<UnifiedSearchOverall> performUnifiedSearch(@Header("Authorization") String authorization,
                                                           @Url String url,

+ 19 - 18
app/src/main/java/com/nextcloud/talk/controllers/ConversationsListController.java

@@ -95,12 +95,12 @@ import com.nextcloud.talk.utils.ApiUtils;
 import com.nextcloud.talk.utils.AttendeePermissionsUtil;
 import com.nextcloud.talk.utils.ClosedInterfaceImpl;
 import com.nextcloud.talk.utils.ConductorRemapping;
-import com.nextcloud.talk.utils.Debouncer;
 import com.nextcloud.talk.utils.DisplayUtils;
 import com.nextcloud.talk.utils.UriUtils;
 import com.nextcloud.talk.utils.bundle.BundleKeys;
 import com.nextcloud.talk.utils.database.user.UserUtils;
 import com.nextcloud.talk.utils.preferences.AppPreferences;
+import com.nextcloud.talk.utils.rx.SearchViewObservable;
 import com.webianks.library.PopupBubble;
 import com.yarolegovich.lovelydialog.LovelySaveStateHandler;
 import com.yarolegovich.lovelydialog.LovelyStandardDialog;
@@ -117,6 +117,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Objects;
+import java.util.concurrent.TimeUnit;
 
 import javax.inject.Inject;
 
@@ -147,8 +148,7 @@ import io.reactivex.schedulers.Schedulers;
 import retrofit2.HttpException;
 
 @AutoInjector(NextcloudTalkApplication.class)
-public class ConversationsListController extends BaseController implements SearchView.OnQueryTextListener,
-    FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, ConversationMenuInterface {
+public class ConversationsListController extends BaseController implements FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, ConversationMenuInterface {
 
     public static final String TAG = "ConvListController";
     public static final int ID_DELETE_CONVERSATION_DIALOG = 0;
@@ -236,9 +236,8 @@ public class ConversationsListController extends BaseController implements Searc
 
     private HashMap<String, Status> userStatuses = new HashMap<>();
 
-    private Debouncer searchDebouncer = new Debouncer(SEARCH_DEBOUNCE_INTERVAL_MS);
-
     private MessageSearchHelper searchHelper;
+    private Disposable searchViewDisposable;
 
     public ConversationsListController(Bundle bundle) {
         super();
@@ -361,7 +360,18 @@ public class ConversationsListController extends BaseController implements Searc
                 if (searchManager != null) {
                     searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
                 }
-                searchView.setOnQueryTextListener(this);
+                searchViewDisposable = SearchViewObservable.observeSearchView(searchView)
+                    .debounce(query -> {
+                        if (TextUtils.isEmpty(query)) {
+                            return Observable.empty();
+                        } else {
+                            return Observable.timer(SEARCH_DEBOUNCE_INTERVAL_MS, TimeUnit.MILLISECONDS);
+                        }
+                    })
+                    .distinctUntilChanged()
+                    .subscribeOn(Schedulers.io())
+                    .observeOn(AndroidSchedulers.mainThread())
+                    .subscribe(this::onQueryTextChange);
             }
         }
     }
@@ -869,21 +879,17 @@ public class ConversationsListController extends BaseController implements Searc
     public void onDestroy() {
         super.onDestroy();
         dispose(null);
+        searchViewDisposable.dispose();
     }
 
-    @Override
-    public boolean onQueryTextChange(final String newText) {
+    public void onQueryTextChange(final String newText) {
         if (!TextUtils.isEmpty(searchQuery)) {
             final String filter = searchQuery;
             searchQuery = "";
             performFilterAndSearch(filter);
         } else if (adapter.hasNewFilter(newText)) {
-            new Handler();
-            searchDebouncer.debounce(() -> {
-                performFilterAndSearch(newText);
-            });
+            performFilterAndSearch(newText);
         }
-        return true;
     }
 
     private void performFilterAndSearch(String filter) {
@@ -939,11 +945,6 @@ public class ConversationsListController extends BaseController implements Searc
     }
 
 
-    @Override
-    public boolean onQueryTextSubmit(String query) {
-        return onQueryTextChange(query);
-    }
-
     @Override
     protected String getTitle() {
         return getResources().getString(R.string.nc_app_product_name);

+ 0 - 34
app/src/main/java/com/nextcloud/talk/utils/Debouncer.kt

@@ -1,34 +0,0 @@
-/*
- * Nextcloud Talk application
- *
- * @author Álvaro Brey
- * Copyright (C) 2022 Álvaro Brey
- * Copyright (C) 2022 Nextcloud GmbH
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
-
-package com.nextcloud.talk.utils
-
-import android.os.Handler
-import android.os.Looper
-
-class Debouncer(var delay: Long) {
-    private val handler = Handler(Looper.getMainLooper())
-
-    fun debounce(runnable: Runnable) {
-        handler.removeCallbacksAndMessages(null) // clear handler
-        handler.postDelayed(runnable, delay)
-    }
-}

+ 48 - 0
app/src/main/java/com/nextcloud/talk/utils/rx/SearchViewObservable.kt

@@ -0,0 +1,48 @@
+/*
+ * Nextcloud Talk application
+ *
+ * @author Álvaro Brey
+ * Copyright (C) 2022 Álvaro Brey
+ * Copyright (C) 2022 Nextcloud GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package com.nextcloud.talk.utils.rx
+
+import androidx.appcompat.widget.SearchView
+import io.reactivex.Observable
+import io.reactivex.subjects.PublishSubject
+
+class SearchViewObservable {
+
+    companion object {
+        @JvmStatic
+        fun observeSearchView(searchView: SearchView): Observable<String> {
+            val subject: PublishSubject<String> = PublishSubject.create()
+            searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
+                override fun onQueryTextSubmit(query: String): Boolean {
+                    subject.onComplete()
+                    return true
+                }
+
+                override fun onQueryTextChange(newText: String): Boolean {
+                    subject.onNext(newText)
+                    return true
+                }
+            })
+            return subject
+        }
+    }
+}