mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Fix category search bug (#3080)
* Closes #3027 * Concat category search with search with image title list and default categories * Fixed unit test CategoriesPresenterTest.searchForCategoriesTest * bug fix [search for categories even when the edit text is empty (perform title based search)] * Category items should show the selected item on top
This commit is contained in:
parent
32715d9cce
commit
8cd9bd5524
6 changed files with 89 additions and 10 deletions
|
|
@ -48,8 +48,21 @@ public class CategoriesModel{
|
||||||
*/
|
*/
|
||||||
public Comparator<CategoryItem> sortBySimilarity(final String filter) {
|
public Comparator<CategoryItem> sortBySimilarity(final String filter) {
|
||||||
Comparator<String> stringSimilarityComparator = StringSortingUtils.sortBySimilarity(filter);
|
Comparator<String> stringSimilarityComparator = StringSortingUtils.sortBySimilarity(filter);
|
||||||
return (firstItem, secondItem) -> stringSimilarityComparator
|
return (firstItem, secondItem) -> {
|
||||||
.compare(firstItem.getName(), secondItem.getName());
|
//if the category is selected, it should get precedence
|
||||||
|
if (null != firstItem && firstItem.isSelected()) {
|
||||||
|
if (null != secondItem && secondItem.isSelected()) {
|
||||||
|
return stringSimilarityComparator
|
||||||
|
.compare(firstItem.getName(), secondItem.getName());
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (null != secondItem && secondItem.isSelected()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return stringSimilarityComparator
|
||||||
|
.compare(firstItem.getName(), secondItem.getName());
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -255,4 +268,38 @@ public class CategoriesModel{
|
||||||
this.categoriesCache.clear();
|
this.categoriesCache.clear();
|
||||||
this.selectedCategories.clear();
|
this.selectedCategories.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search for categories
|
||||||
|
*/
|
||||||
|
public Observable<CategoryItem> searchCategories(String query, List<String> imageTitleList) {
|
||||||
|
if (TextUtils.isEmpty(query)) {
|
||||||
|
return gpsCategories()
|
||||||
|
.concatWith(titleCategories(imageTitleList))
|
||||||
|
.concatWith(recentCategories());
|
||||||
|
}
|
||||||
|
|
||||||
|
return mwApi
|
||||||
|
.searchCategories(query, SEARCH_CATS_LIMIT)
|
||||||
|
.map(s -> new CategoryItem(s, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns default categories
|
||||||
|
*/
|
||||||
|
public Observable<CategoryItem> getDefaultCategories(List<String> titleList) {
|
||||||
|
Observable<CategoryItem> directCategories = directCategories();
|
||||||
|
if (hasDirectCategories()) {
|
||||||
|
Timber.d("Image has direct Categories");
|
||||||
|
return directCategories
|
||||||
|
.concatWith(gpsCategories())
|
||||||
|
.concatWith(titleCategories(titleList))
|
||||||
|
.concatWith(recentCategories());
|
||||||
|
} else {
|
||||||
|
Timber.d("Image has no direct Categories");
|
||||||
|
return gpsCategories()
|
||||||
|
.concatWith(titleCategories(titleList))
|
||||||
|
.concatWith(recentCategories());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,8 @@ import fr.free.nrw.commons.upload.UploadModel;
|
||||||
import fr.free.nrw.commons.upload.UploadModel.UploadItem;
|
import fr.free.nrw.commons.upload.UploadModel.UploadItem;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
|
@ -167,7 +165,7 @@ public class UploadRemoteDataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ask the UplaodModel for the image quality of the UploadItem
|
* ask the UploadModel for the image quality of the UploadItem
|
||||||
*
|
*
|
||||||
* @param uploadItem
|
* @param uploadItem
|
||||||
* @param shouldValidateTitle
|
* @param shouldValidateTitle
|
||||||
|
|
@ -176,4 +174,21 @@ public class UploadRemoteDataSource {
|
||||||
public Single<Integer> getImageQuality(UploadItem uploadItem, boolean shouldValidateTitle) {
|
public Single<Integer> getImageQuality(UploadItem uploadItem, boolean shouldValidateTitle) {
|
||||||
return uploadModel.getImageQuality(uploadItem, shouldValidateTitle);
|
return uploadModel.getImageQuality(uploadItem, shouldValidateTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the CategoriesModel to search categories
|
||||||
|
* @param query
|
||||||
|
* @param imageTitleList
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Observable<CategoryItem> searchCategories(String query, List<String> imageTitleList) {
|
||||||
|
return categoriesModel.searchCategories(query, imageTitleList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the CategoriesModel for default categories
|
||||||
|
*/
|
||||||
|
public Observable<CategoryItem> getDefaultCategories(List<String> imageTitleList) {
|
||||||
|
return categoriesModel.getDefaultCategories(imageTitleList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,10 +8,8 @@ import fr.free.nrw.commons.upload.SimilarImageInterface;
|
||||||
import fr.free.nrw.commons.upload.UploadModel.UploadItem;
|
import fr.free.nrw.commons.upload.UploadModel.UploadItem;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
|
@ -262,4 +260,18 @@ public class UploadRepository {
|
||||||
public void setSelectedLicense(String licenseName) {
|
public void setSelectedLicense(String licenseName) {
|
||||||
localDataSource.setSelectedLicense(licenseName);
|
localDataSource.setSelectedLicense(licenseName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the RemoteDataSource to search for categories
|
||||||
|
*/
|
||||||
|
public Observable<CategoryItem> searchCategories(String query, List<String> imageTitleList) {
|
||||||
|
return remoteDataSource.searchCategories(query, imageTitleList);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the RemoteDataSource to get default categories
|
||||||
|
*/
|
||||||
|
public Observable<CategoryItem> getDefaultCategories(List<String> imageTitleList) {
|
||||||
|
return remoteDataSource.getDefaultCategories(imageTitleList);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,9 @@ public class CategoriesPresenter implements CategoriesContract.UserActionListene
|
||||||
.observeOn(ioScheduler)
|
.observeOn(ioScheduler)
|
||||||
.concatWith(
|
.concatWith(
|
||||||
repository.searchAll(query, imageTitleList)
|
repository.searchAll(query, imageTitleList)
|
||||||
|
.mergeWith(repository.searchCategories(query, imageTitleList))
|
||||||
|
.concatWith(TextUtils.isEmpty(query) ? repository
|
||||||
|
.getDefaultCategories(imageTitleList) : Observable.empty())
|
||||||
)
|
)
|
||||||
.filter(categoryItem -> !repository.containsYear(categoryItem.getName()))
|
.filter(categoryItem -> !repository.containsYear(categoryItem.getName()))
|
||||||
.distinct();
|
.distinct();
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (presenter != null && isVisible && (categories == null || categories.isEmpty())) {
|
if (presenter != null && isVisible) {
|
||||||
presenter.searchForCategories(null);
|
presenter.searchForCategories(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -193,7 +193,7 @@ public class UploadCategoriesFragment extends UploadBaseFragment implements Cate
|
||||||
super.setUserVisibleHint(isVisibleToUser);
|
super.setUserVisibleHint(isVisibleToUser);
|
||||||
isVisible = isVisibleToUser;
|
isVisible = isVisibleToUser;
|
||||||
|
|
||||||
if (presenter != null && isResumed() && (categories == null || categories.isEmpty())) {
|
if (presenter != null && isResumed()) {
|
||||||
presenter.searchForCategories(null);
|
presenter.searchForCategories(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,9 @@ class CategoriesPresenterTest {
|
||||||
fun searchForCategoriesTest() {
|
fun searchForCategoriesTest() {
|
||||||
Mockito.`when`(repository?.sortBySimilarity(ArgumentMatchers.anyString())).thenReturn(Comparator<CategoryItem> { _, _ -> 1 })
|
Mockito.`when`(repository?.sortBySimilarity(ArgumentMatchers.anyString())).thenReturn(Comparator<CategoryItem> { _, _ -> 1 })
|
||||||
Mockito.`when`(repository?.selectedCategories).thenReturn(categoryItems)
|
Mockito.`when`(repository?.selectedCategories).thenReturn(categoryItems)
|
||||||
Mockito.`when`(repository?.searchAll(ArgumentMatchers.anyString(), ArgumentMatchers.anyList())).thenReturn(Observable.empty())
|
Mockito.`when`(repository?.searchAll(ArgumentMatchers.anyString(), ArgumentMatchers.anyList())).thenReturn(testObservable)
|
||||||
|
Mockito.`when`(repository?.searchCategories(ArgumentMatchers.anyString(), ArgumentMatchers.anyList())).thenReturn(testObservable)
|
||||||
|
Mockito.`when`(repository?.getDefaultCategories(ArgumentMatchers.anyList())).thenReturn(testObservable)
|
||||||
categoriesPresenter?.searchForCategories("test")
|
categoriesPresenter?.searchForCategories("test")
|
||||||
verify(view)?.showProgress(true)
|
verify(view)?.showProgress(true)
|
||||||
verify(view)?.showError(null)
|
verify(view)?.showError(null)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue