mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-19 19:49:33 +01:00
Use rxjava to debounce search instead of custom debouncer
Signed-off-by: Álvaro Brey <alvaro.brey@nextcloud.com>
This commit is contained in:
parent
b10ea2f41f
commit
d1d61e87a9
@ -66,7 +66,6 @@ import retrofit2.http.FieldMap;
|
|||||||
import retrofit2.http.FormUrlEncoded;
|
import retrofit2.http.FormUrlEncoded;
|
||||||
import retrofit2.http.GET;
|
import retrofit2.http.GET;
|
||||||
import retrofit2.http.Header;
|
import retrofit2.http.Header;
|
||||||
import retrofit2.http.Headers;
|
|
||||||
import retrofit2.http.Multipart;
|
import retrofit2.http.Multipart;
|
||||||
import retrofit2.http.POST;
|
import retrofit2.http.POST;
|
||||||
import retrofit2.http.PUT;
|
import retrofit2.http.PUT;
|
||||||
@ -521,7 +520,6 @@ public interface NcApi {
|
|||||||
@Url String url,
|
@Url String url,
|
||||||
@Query("reaction") String reaction);
|
@Query("reaction") String reaction);
|
||||||
|
|
||||||
// TODO use path params instead of passing URL
|
|
||||||
@GET
|
@GET
|
||||||
Observable<UnifiedSearchOverall> performUnifiedSearch(@Header("Authorization") String authorization,
|
Observable<UnifiedSearchOverall> performUnifiedSearch(@Header("Authorization") String authorization,
|
||||||
@Url String url,
|
@Url String url,
|
||||||
|
@ -95,12 +95,12 @@ import com.nextcloud.talk.utils.ApiUtils;
|
|||||||
import com.nextcloud.talk.utils.AttendeePermissionsUtil;
|
import com.nextcloud.talk.utils.AttendeePermissionsUtil;
|
||||||
import com.nextcloud.talk.utils.ClosedInterfaceImpl;
|
import com.nextcloud.talk.utils.ClosedInterfaceImpl;
|
||||||
import com.nextcloud.talk.utils.ConductorRemapping;
|
import com.nextcloud.talk.utils.ConductorRemapping;
|
||||||
import com.nextcloud.talk.utils.Debouncer;
|
|
||||||
import com.nextcloud.talk.utils.DisplayUtils;
|
import com.nextcloud.talk.utils.DisplayUtils;
|
||||||
import com.nextcloud.talk.utils.UriUtils;
|
import com.nextcloud.talk.utils.UriUtils;
|
||||||
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
import com.nextcloud.talk.utils.bundle.BundleKeys;
|
||||||
import com.nextcloud.talk.utils.database.user.UserUtils;
|
import com.nextcloud.talk.utils.database.user.UserUtils;
|
||||||
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
import com.nextcloud.talk.utils.preferences.AppPreferences;
|
||||||
|
import com.nextcloud.talk.utils.rx.SearchViewObservable;
|
||||||
import com.webianks.library.PopupBubble;
|
import com.webianks.library.PopupBubble;
|
||||||
import com.yarolegovich.lovelydialog.LovelySaveStateHandler;
|
import com.yarolegovich.lovelydialog.LovelySaveStateHandler;
|
||||||
import com.yarolegovich.lovelydialog.LovelyStandardDialog;
|
import com.yarolegovich.lovelydialog.LovelyStandardDialog;
|
||||||
@ -117,6 +117,7 @@ import java.util.Collections;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
@ -147,8 +148,7 @@ import io.reactivex.schedulers.Schedulers;
|
|||||||
import retrofit2.HttpException;
|
import retrofit2.HttpException;
|
||||||
|
|
||||||
@AutoInjector(NextcloudTalkApplication.class)
|
@AutoInjector(NextcloudTalkApplication.class)
|
||||||
public class ConversationsListController extends BaseController implements SearchView.OnQueryTextListener,
|
public class ConversationsListController extends BaseController implements FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, ConversationMenuInterface {
|
||||||
FlexibleAdapter.OnItemClickListener, FlexibleAdapter.OnItemLongClickListener, ConversationMenuInterface {
|
|
||||||
|
|
||||||
public static final String TAG = "ConvListController";
|
public static final String TAG = "ConvListController";
|
||||||
public static final int ID_DELETE_CONVERSATION_DIALOG = 0;
|
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 HashMap<String, Status> userStatuses = new HashMap<>();
|
||||||
|
|
||||||
private Debouncer searchDebouncer = new Debouncer(SEARCH_DEBOUNCE_INTERVAL_MS);
|
|
||||||
|
|
||||||
private MessageSearchHelper searchHelper;
|
private MessageSearchHelper searchHelper;
|
||||||
|
private Disposable searchViewDisposable;
|
||||||
|
|
||||||
public ConversationsListController(Bundle bundle) {
|
public ConversationsListController(Bundle bundle) {
|
||||||
super();
|
super();
|
||||||
@ -361,7 +360,18 @@ public class ConversationsListController extends BaseController implements Searc
|
|||||||
if (searchManager != null) {
|
if (searchManager != null) {
|
||||||
searchView.setSearchableInfo(searchManager.getSearchableInfo(getActivity().getComponentName()));
|
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() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
dispose(null);
|
dispose(null);
|
||||||
|
searchViewDisposable.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void onQueryTextChange(final String newText) {
|
||||||
public boolean onQueryTextChange(final String newText) {
|
|
||||||
if (!TextUtils.isEmpty(searchQuery)) {
|
if (!TextUtils.isEmpty(searchQuery)) {
|
||||||
final String filter = searchQuery;
|
final String filter = searchQuery;
|
||||||
searchQuery = "";
|
searchQuery = "";
|
||||||
performFilterAndSearch(filter);
|
performFilterAndSearch(filter);
|
||||||
} else if (adapter.hasNewFilter(newText)) {
|
} else if (adapter.hasNewFilter(newText)) {
|
||||||
new Handler();
|
performFilterAndSearch(newText);
|
||||||
searchDebouncer.debounce(() -> {
|
|
||||||
performFilterAndSearch(newText);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void performFilterAndSearch(String filter) {
|
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
|
@Override
|
||||||
protected String getTitle() {
|
protected String getTitle() {
|
||||||
return getResources().getString(R.string.nc_app_product_name);
|
return getResources().getString(R.string.nc_app_product_name);
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user