mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 04:43:54 +01:00
Displaying Category image and Description (#4531)
* API call done * API call * Image implementation done * Gradle * Java docs and code convention * Description added * Refactoring Category * Refactoring Category * Refactoring Category * Description and thumbnail issue fixed * Description and thumbnail issue fixed * Minor issue fixed * Minor issue fixed * Server changed * Logo changed * Change in structure * Fixed failed tests * Fixed Test failed * Optimized imports * Dialog can't be dismissed * Dialog can't be dismissed * Resolved Conflicts * UI fixed * Added description and thumbnail in local DB * Added description and thumbnail in local DB * Test fixed * Added * Updated with latest master * Test Updated with latest master * Issue fixed * Revert gradle changes * Revert gradle changes * Update gradle-wrapper.properties * Require Api removed
This commit is contained in:
parent
0914eeea53
commit
92957f4204
31 changed files with 373 additions and 151 deletions
|
|
@ -5,6 +5,7 @@ import android.content.ContentValues;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem;
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
@ -141,9 +142,17 @@ public class BookmarkItemsDao {
|
||||||
final String instanceListString
|
final String instanceListString
|
||||||
= cursor.getString(cursor.getColumnIndex(Table.COLUMN_INSTANCE_LIST));
|
= cursor.getString(cursor.getColumnIndex(Table.COLUMN_INSTANCE_LIST));
|
||||||
final List<String> instanceList = StringToArray(instanceListString);
|
final List<String> instanceList = StringToArray(instanceListString);
|
||||||
final String categoryListString = cursor.getString(cursor
|
final String categoryNameListString = cursor.getString(cursor
|
||||||
.getColumnIndex(Table.COLUMN_CATEGORIES_LIST));
|
.getColumnIndex(Table.COLUMN_CATEGORIES_NAME_LIST));
|
||||||
final List<String> categoryList = StringToArray(categoryListString);
|
final List<String> categoryNameList = StringToArray(categoryNameListString);
|
||||||
|
final String categoryDescriptionListString = cursor.getString(cursor
|
||||||
|
.getColumnIndex(Table.COLUMN_CATEGORIES_DESCRIPTION_LIST));
|
||||||
|
final List<String> categoryDescriptionList = StringToArray(categoryDescriptionListString);
|
||||||
|
final String categoryThumbnailListString = cursor.getString(cursor
|
||||||
|
.getColumnIndex(Table.COLUMN_CATEGORIES_THUMBNAIL_LIST));
|
||||||
|
final List<String> categoryThumbnailList = StringToArray(categoryThumbnailListString);
|
||||||
|
final List<CategoryItem> categoryList = convertToCategoryItems(categoryNameList,
|
||||||
|
categoryDescriptionList, categoryThumbnailList);
|
||||||
final boolean isSelected
|
final boolean isSelected
|
||||||
= Boolean.parseBoolean(cursor.getString(cursor
|
= Boolean.parseBoolean(cursor.getString(cursor
|
||||||
.getColumnIndex(Table.COLUMN_IS_SELECTED)));
|
.getColumnIndex(Table.COLUMN_IS_SELECTED)));
|
||||||
|
|
@ -160,6 +169,17 @@ public class BookmarkItemsDao {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<CategoryItem> convertToCategoryItems(List<String> categoryNameList,
|
||||||
|
List<String> categoryDescriptionList, List<String> categoryThumbnailList) {
|
||||||
|
List<CategoryItem> categoryItems = new ArrayList<>();
|
||||||
|
for(int i=0; i<categoryNameList.size(); i++){
|
||||||
|
categoryItems.add(new CategoryItem(categoryNameList.get(i),
|
||||||
|
categoryDescriptionList.get(i),
|
||||||
|
categoryThumbnailList.get(i), false));
|
||||||
|
}
|
||||||
|
return categoryItems;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts string to List
|
* Converts string to List
|
||||||
* @param listString comma separated single string from of list items
|
* @param listString comma separated single string from of list items
|
||||||
|
|
@ -188,12 +208,35 @@ public class BookmarkItemsDao {
|
||||||
* @return ContentValues
|
* @return ContentValues
|
||||||
*/
|
*/
|
||||||
private ContentValues toContentValues(final DepictedItem depictedItem) {
|
private ContentValues toContentValues(final DepictedItem depictedItem) {
|
||||||
|
|
||||||
|
final List<String> namesOfCommonsCategories = new ArrayList<>();
|
||||||
|
for (final CategoryItem category :
|
||||||
|
depictedItem.getCommonsCategories()) {
|
||||||
|
namesOfCommonsCategories.add(category.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> descriptionsOfCommonsCategories = new ArrayList<>();
|
||||||
|
for (final CategoryItem category :
|
||||||
|
depictedItem.getCommonsCategories()) {
|
||||||
|
descriptionsOfCommonsCategories.add(category.getDescription());
|
||||||
|
}
|
||||||
|
|
||||||
|
final List<String> thumbnailsOfCommonsCategories = new ArrayList<>();
|
||||||
|
for (final CategoryItem category :
|
||||||
|
depictedItem.getCommonsCategories()) {
|
||||||
|
thumbnailsOfCommonsCategories.add(category.getThumbnail());
|
||||||
|
}
|
||||||
|
|
||||||
final ContentValues cv = new ContentValues();
|
final ContentValues cv = new ContentValues();
|
||||||
cv.put(Table.COLUMN_NAME, depictedItem.getName());
|
cv.put(Table.COLUMN_NAME, depictedItem.getName());
|
||||||
cv.put(Table.COLUMN_DESCRIPTION, depictedItem.getDescription());
|
cv.put(Table.COLUMN_DESCRIPTION, depictedItem.getDescription());
|
||||||
cv.put(Table.COLUMN_IMAGE, depictedItem.getImageUrl());
|
cv.put(Table.COLUMN_IMAGE, depictedItem.getImageUrl());
|
||||||
cv.put(Table.COLUMN_INSTANCE_LIST, ArrayToString(depictedItem.getInstanceOfs()));
|
cv.put(Table.COLUMN_INSTANCE_LIST, ArrayToString(depictedItem.getInstanceOfs()));
|
||||||
cv.put(Table.COLUMN_CATEGORIES_LIST, ArrayToString(depictedItem.getCommonsCategories()));
|
cv.put(Table.COLUMN_CATEGORIES_NAME_LIST, ArrayToString(namesOfCommonsCategories));
|
||||||
|
cv.put(Table.COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
||||||
|
ArrayToString(descriptionsOfCommonsCategories));
|
||||||
|
cv.put(Table.COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
||||||
|
ArrayToString(thumbnailsOfCommonsCategories));
|
||||||
cv.put(Table.COLUMN_IS_SELECTED, depictedItem.isSelected());
|
cv.put(Table.COLUMN_IS_SELECTED, depictedItem.isSelected());
|
||||||
cv.put(Table.COLUMN_ID, depictedItem.getId());
|
cv.put(Table.COLUMN_ID, depictedItem.getId());
|
||||||
return cv;
|
return cv;
|
||||||
|
|
@ -208,7 +251,9 @@ public class BookmarkItemsDao {
|
||||||
public static final String COLUMN_DESCRIPTION = "item_description";
|
public static final String COLUMN_DESCRIPTION = "item_description";
|
||||||
public static final String COLUMN_IMAGE = "item_image_url";
|
public static final String COLUMN_IMAGE = "item_image_url";
|
||||||
public static final String COLUMN_INSTANCE_LIST = "item_instance_of";
|
public static final String COLUMN_INSTANCE_LIST = "item_instance_of";
|
||||||
public static final String COLUMN_CATEGORIES_LIST = "item_categories";
|
public static final String COLUMN_CATEGORIES_NAME_LIST = "item_name_categories";
|
||||||
|
public static final String COLUMN_CATEGORIES_DESCRIPTION_LIST = "item_description_categories";
|
||||||
|
public static final String COLUMN_CATEGORIES_THUMBNAIL_LIST = "item_thumbnail_categories";
|
||||||
public static final String COLUMN_IS_SELECTED = "item_is_selected";
|
public static final String COLUMN_IS_SELECTED = "item_is_selected";
|
||||||
public static final String COLUMN_ID = "item_id";
|
public static final String COLUMN_ID = "item_id";
|
||||||
|
|
||||||
|
|
@ -217,7 +262,9 @@ public class BookmarkItemsDao {
|
||||||
COLUMN_DESCRIPTION,
|
COLUMN_DESCRIPTION,
|
||||||
COLUMN_IMAGE,
|
COLUMN_IMAGE,
|
||||||
COLUMN_INSTANCE_LIST,
|
COLUMN_INSTANCE_LIST,
|
||||||
COLUMN_CATEGORIES_LIST,
|
COLUMN_CATEGORIES_NAME_LIST,
|
||||||
|
COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
||||||
|
COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
||||||
COLUMN_IS_SELECTED,
|
COLUMN_IS_SELECTED,
|
||||||
COLUMN_ID
|
COLUMN_ID
|
||||||
};
|
};
|
||||||
|
|
@ -228,7 +275,9 @@ public class BookmarkItemsDao {
|
||||||
+ COLUMN_DESCRIPTION + " STRING,"
|
+ COLUMN_DESCRIPTION + " STRING,"
|
||||||
+ COLUMN_IMAGE + " STRING,"
|
+ COLUMN_IMAGE + " STRING,"
|
||||||
+ COLUMN_INSTANCE_LIST + " STRING,"
|
+ COLUMN_INSTANCE_LIST + " STRING,"
|
||||||
+ COLUMN_CATEGORIES_LIST + " STRING,"
|
+ COLUMN_CATEGORIES_NAME_LIST + " STRING,"
|
||||||
|
+ COLUMN_CATEGORIES_DESCRIPTION_LIST + " STRING,"
|
||||||
|
+ COLUMN_CATEGORIES_THUMBNAIL_LIST + " STRING,"
|
||||||
+ COLUMN_IS_SELECTED + " STRING,"
|
+ COLUMN_IS_SELECTED + " STRING,"
|
||||||
+ COLUMN_ID + " STRING PRIMARY KEY"
|
+ COLUMN_ID + " STRING PRIMARY KEY"
|
||||||
+ ");";
|
+ ");";
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ class CategoriesModel @Inject constructor(
|
||||||
|
|
||||||
// Newly used category...
|
// Newly used category...
|
||||||
if (category == null) {
|
if (category == null) {
|
||||||
category = Category(null, item.name, Date(), 0)
|
category = Category(null, item.name, item.description, item.thumbnail, Date(), 0)
|
||||||
}
|
}
|
||||||
category.incTimesUsed()
|
category.incTimesUsed()
|
||||||
categoryDao.save(category)
|
categoryDao.save(category)
|
||||||
|
|
@ -74,14 +74,14 @@ class CategoriesModel @Inject constructor(
|
||||||
selectedDepictions: List<DepictedItem>
|
selectedDepictions: List<DepictedItem>
|
||||||
): Observable<List<CategoryItem>> {
|
): Observable<List<CategoryItem>> {
|
||||||
return suggestionsOrSearch(term, imageTitleList, selectedDepictions)
|
return suggestionsOrSearch(term, imageTitleList, selectedDepictions)
|
||||||
.map { it.map { CategoryItem(it, false) } }
|
.map { it.map { CategoryItem(it.name, it.description, it.thumbnail, false) } }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun suggestionsOrSearch(
|
private fun suggestionsOrSearch(
|
||||||
term: String,
|
term: String,
|
||||||
imageTitleList: List<String>,
|
imageTitleList: List<String>,
|
||||||
selectedDepictions: List<DepictedItem>
|
selectedDepictions: List<DepictedItem>
|
||||||
): Observable<List<String>> {
|
): Observable<List<CategoryItem>> {
|
||||||
return if (TextUtils.isEmpty(term))
|
return if (TextUtils.isEmpty(term))
|
||||||
Observable.combineLatest(
|
Observable.combineLatest(
|
||||||
categoriesFromDepiction(selectedDepictions),
|
categoriesFromDepiction(selectedDepictions),
|
||||||
|
|
@ -100,10 +100,10 @@ class CategoriesModel @Inject constructor(
|
||||||
Observable.just(selectedDepictions.map { it.commonsCategories }.flatten())
|
Observable.just(selectedDepictions.map { it.commonsCategories }.flatten())
|
||||||
|
|
||||||
private fun combine(
|
private fun combine(
|
||||||
depictionCategories: List<String>,
|
depictionCategories: List<CategoryItem>,
|
||||||
locationCategories: List<String>,
|
locationCategories: List<CategoryItem>,
|
||||||
titles: List<String>,
|
titles: List<CategoryItem>,
|
||||||
recents: List<String>
|
recents: List<CategoryItem>
|
||||||
) = depictionCategories + locationCategories + titles + recents
|
) = depictionCategories + locationCategories + titles + recents
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -115,7 +115,7 @@ class CategoriesModel @Inject constructor(
|
||||||
private fun titleCategories(titleList: List<String>) =
|
private fun titleCategories(titleList: List<String>) =
|
||||||
if (titleList.isNotEmpty())
|
if (titleList.isNotEmpty())
|
||||||
Observable.combineLatest(titleList.map { getTitleCategories(it) }) { searchResults ->
|
Observable.combineLatest(titleList.map { getTitleCategories(it) }) { searchResults ->
|
||||||
searchResults.map { it as List<String> }.flatten()
|
searchResults.map { it as List<CategoryItem> }.flatten()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Observable.just(emptyList())
|
Observable.just(emptyList())
|
||||||
|
|
@ -125,7 +125,7 @@ class CategoriesModel @Inject constructor(
|
||||||
* @param title
|
* @param title
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private fun getTitleCategories(title: String): Observable<List<String>> {
|
private fun getTitleCategories(title: String): Observable<List<CategoryItem>> {
|
||||||
return categoryClient.searchCategories(title, SEARCH_CATS_LIMIT).toObservable()
|
return categoryClient.searchCategories(title, SEARCH_CATS_LIMIT).toObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,15 +10,19 @@ import java.util.Date;
|
||||||
public class Category {
|
public class Category {
|
||||||
private Uri contentUri;
|
private Uri contentUri;
|
||||||
private String name;
|
private String name;
|
||||||
|
private String description;
|
||||||
|
private String thumbnail;
|
||||||
private Date lastUsed;
|
private Date lastUsed;
|
||||||
private int timesUsed;
|
private int timesUsed;
|
||||||
|
|
||||||
public Category() {
|
public Category() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Category(Uri contentUri, String name, Date lastUsed, int timesUsed) {
|
public Category(Uri contentUri, String name, String description, String thumbnail, Date lastUsed, int timesUsed) {
|
||||||
this.contentUri = contentUri;
|
this.contentUri = contentUri;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
this.description = description;
|
||||||
|
this.thumbnail = thumbnail;
|
||||||
this.lastUsed = lastUsed;
|
this.lastUsed = lastUsed;
|
||||||
this.timesUsed = timesUsed;
|
this.timesUsed = timesUsed;
|
||||||
}
|
}
|
||||||
|
|
@ -93,4 +97,19 @@ public class Category {
|
||||||
this.contentUri = contentUri;
|
this.contentUri = contentUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getThumbnail() {
|
||||||
|
return thumbnail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescription(final String description) {
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setThumbnail(final String thumbnail) {
|
||||||
|
this.thumbnail = thumbnail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ const val CATEGORY_NEEDING_CATEGORIES = "needing categories"
|
||||||
*/
|
*/
|
||||||
@Singleton
|
@Singleton
|
||||||
class CategoryClient @Inject constructor(private val categoryInterface: CategoryInterface) :
|
class CategoryClient @Inject constructor(private val categoryInterface: CategoryInterface) :
|
||||||
ContinuationClient<MwQueryResponse, String>() {
|
ContinuationClient<MwQueryResponse, CategoryItem>() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for categories containing the specified string.
|
* Searches for categories containing the specified string.
|
||||||
|
|
@ -28,7 +28,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun searchCategories(filter: String?, itemLimit: Int, offset: Int = 0):
|
fun searchCategories(filter: String?, itemLimit: Int, offset: Int = 0):
|
||||||
Single<List<String>> {
|
Single<List<CategoryItem>> {
|
||||||
return responseMapper(categoryInterface.searchCategories(filter, itemLimit, offset))
|
return responseMapper(categoryInterface.searchCategories(filter, itemLimit, offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -42,7 +42,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
*/
|
*/
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
fun searchCategoriesForPrefix(prefix: String?, itemLimit: Int, offset: Int = 0):
|
fun searchCategoriesForPrefix(prefix: String?, itemLimit: Int, offset: Int = 0):
|
||||||
Single<List<String>> {
|
Single<List<CategoryItem>> {
|
||||||
return responseMapper(
|
return responseMapper(
|
||||||
categoryInterface.searchCategoriesForPrefix(prefix, itemLimit, offset)
|
categoryInterface.searchCategoriesForPrefix(prefix, itemLimit, offset)
|
||||||
)
|
)
|
||||||
|
|
@ -55,7 +55,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
* @param categoryName Category name as defined on commons
|
* @param categoryName Category name as defined on commons
|
||||||
* @return Observable emitting the categories returned. If our search yielded "Category:Test", "Test" is emitted.
|
* @return Observable emitting the categories returned. If our search yielded "Category:Test", "Test" is emitted.
|
||||||
*/
|
*/
|
||||||
fun getSubCategoryList(categoryName: String): Single<List<String>> {
|
fun getSubCategoryList(categoryName: String): Single<List<CategoryItem>> {
|
||||||
return continuationRequest(SUB_CATEGORY_CONTINUATION_PREFIX, categoryName) {
|
return continuationRequest(SUB_CATEGORY_CONTINUATION_PREFIX, categoryName) {
|
||||||
categoryInterface.getSubCategoryList(
|
categoryInterface.getSubCategoryList(
|
||||||
categoryName, it
|
categoryName, it
|
||||||
|
|
@ -70,7 +70,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
* @param categoryName Category name as defined on commons
|
* @param categoryName Category name as defined on commons
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
fun getParentCategoryList(categoryName: String): Single<List<String>> {
|
fun getParentCategoryList(categoryName: String): Single<List<CategoryItem>> {
|
||||||
return continuationRequest(PARENT_CATEGORY_CONTINUATION_PREFIX, categoryName) {
|
return continuationRequest(PARENT_CATEGORY_CONTINUATION_PREFIX, categoryName) {
|
||||||
categoryInterface.getParentCategoryList(categoryName, it)
|
categoryInterface.getParentCategoryList(categoryName, it)
|
||||||
}
|
}
|
||||||
|
|
@ -87,7 +87,7 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
override fun responseMapper(
|
override fun responseMapper(
|
||||||
networkResult: Single<MwQueryResponse>,
|
networkResult: Single<MwQueryResponse>,
|
||||||
key: String?
|
key: String?
|
||||||
): Single<List<String>> {
|
): Single<List<CategoryItem>> {
|
||||||
return networkResult
|
return networkResult
|
||||||
.map {
|
.map {
|
||||||
handleContinuationResponse(it.continuation(), key)
|
handleContinuationResponse(it.continuation(), key)
|
||||||
|
|
@ -96,7 +96,10 @@ class CategoryClient @Inject constructor(private val categoryInterface: Category
|
||||||
.map {
|
.map {
|
||||||
it.filter {
|
it.filter {
|
||||||
page -> page.categoryInfo() == null || !page.categoryInfo().isHidden
|
page -> page.categoryInfo() == null || !page.categoryInfo().isHidden
|
||||||
}.map { page -> page.title().replace(CATEGORY_PREFIX, "") }
|
}.map {
|
||||||
|
CategoryItem(it.title().replace(CATEGORY_PREFIX, ""),
|
||||||
|
it.description().toString(), it.thumbUrl().toString(), false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,8 +79,8 @@ public class CategoryDao {
|
||||||
* @return a list containing recent categories
|
* @return a list containing recent categories
|
||||||
*/
|
*/
|
||||||
@NonNull
|
@NonNull
|
||||||
List<String> recentCategories(int limit) {
|
List<CategoryItem> recentCategories(int limit) {
|
||||||
List<String> items = new ArrayList<>();
|
List<CategoryItem> items = new ArrayList<>();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
ContentProviderClient db = clientProvider.get();
|
ContentProviderClient db = clientProvider.get();
|
||||||
try {
|
try {
|
||||||
|
|
@ -93,7 +93,9 @@ public class CategoryDao {
|
||||||
// fixme add a limit on the original query instead of falling out of the loop?
|
// fixme add a limit on the original query instead of falling out of the loop?
|
||||||
while (cursor != null && cursor.moveToNext()
|
while (cursor != null && cursor.moveToNext()
|
||||||
&& cursor.getPosition() < limit) {
|
&& cursor.getPosition() < limit) {
|
||||||
items.add(fromCursor(cursor).getName());
|
items.add(new CategoryItem(fromCursor(cursor).getName(),
|
||||||
|
fromCursor(cursor).getDescription(), fromCursor(cursor).getThumbnail(),
|
||||||
|
false));
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
|
@ -112,6 +114,8 @@ public class CategoryDao {
|
||||||
return new Category(
|
return new Category(
|
||||||
CategoryContentProvider.uriForId(cursor.getInt(cursor.getColumnIndex(Table.COLUMN_ID))),
|
CategoryContentProvider.uriForId(cursor.getInt(cursor.getColumnIndex(Table.COLUMN_ID))),
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
|
||||||
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_THUMBNAIL)),
|
||||||
new Date(cursor.getLong(cursor.getColumnIndex(Table.COLUMN_LAST_USED))),
|
new Date(cursor.getLong(cursor.getColumnIndex(Table.COLUMN_LAST_USED))),
|
||||||
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_TIMES_USED))
|
cursor.getInt(cursor.getColumnIndex(Table.COLUMN_TIMES_USED))
|
||||||
);
|
);
|
||||||
|
|
@ -120,6 +124,8 @@ public class CategoryDao {
|
||||||
private ContentValues toContentValues(Category category) {
|
private ContentValues toContentValues(Category category) {
|
||||||
ContentValues cv = new ContentValues();
|
ContentValues cv = new ContentValues();
|
||||||
cv.put(CategoryDao.Table.COLUMN_NAME, category.getName());
|
cv.put(CategoryDao.Table.COLUMN_NAME, category.getName());
|
||||||
|
cv.put(Table.COLUMN_DESCRIPTION, category.getDescription());
|
||||||
|
cv.put(Table.COLUMN_THUMBNAIL, category.getThumbnail());
|
||||||
cv.put(CategoryDao.Table.COLUMN_LAST_USED, category.getLastUsed().getTime());
|
cv.put(CategoryDao.Table.COLUMN_LAST_USED, category.getLastUsed().getTime());
|
||||||
cv.put(CategoryDao.Table.COLUMN_TIMES_USED, category.getTimesUsed());
|
cv.put(CategoryDao.Table.COLUMN_TIMES_USED, category.getTimesUsed());
|
||||||
return cv;
|
return cv;
|
||||||
|
|
@ -130,6 +136,8 @@ public class CategoryDao {
|
||||||
|
|
||||||
public static final String COLUMN_ID = "_id";
|
public static final String COLUMN_ID = "_id";
|
||||||
static final String COLUMN_NAME = "name";
|
static final String COLUMN_NAME = "name";
|
||||||
|
static final String COLUMN_DESCRIPTION = "description";
|
||||||
|
static final String COLUMN_THUMBNAIL = "thumbnail";
|
||||||
static final String COLUMN_LAST_USED = "last_used";
|
static final String COLUMN_LAST_USED = "last_used";
|
||||||
static final String COLUMN_TIMES_USED = "times_used";
|
static final String COLUMN_TIMES_USED = "times_used";
|
||||||
|
|
||||||
|
|
@ -137,6 +145,8 @@ public class CategoryDao {
|
||||||
public static final String[] ALL_FIELDS = {
|
public static final String[] ALL_FIELDS = {
|
||||||
COLUMN_ID,
|
COLUMN_ID,
|
||||||
COLUMN_NAME,
|
COLUMN_NAME,
|
||||||
|
COLUMN_DESCRIPTION,
|
||||||
|
COLUMN_THUMBNAIL,
|
||||||
COLUMN_LAST_USED,
|
COLUMN_LAST_USED,
|
||||||
COLUMN_TIMES_USED
|
COLUMN_TIMES_USED
|
||||||
};
|
};
|
||||||
|
|
@ -146,6 +156,8 @@ public class CategoryDao {
|
||||||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
||||||
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
|
+ COLUMN_ID + " INTEGER PRIMARY KEY,"
|
||||||
+ COLUMN_NAME + " STRING,"
|
+ COLUMN_NAME + " STRING,"
|
||||||
|
+ COLUMN_DESCRIPTION + " STRING,"
|
||||||
|
+ COLUMN_THUMBNAIL + " STRING,"
|
||||||
+ COLUMN_LAST_USED + " INTEGER,"
|
+ COLUMN_LAST_USED + " INTEGER,"
|
||||||
+ COLUMN_TIMES_USED + " INTEGER"
|
+ COLUMN_TIMES_USED + " INTEGER"
|
||||||
+ ");";
|
+ ");";
|
||||||
|
|
|
||||||
|
|
@ -94,8 +94,14 @@ public class CategoryEditSearchRecyclerViewAdapter
|
||||||
@Override
|
@Override
|
||||||
protected FilterResults performFiltering(CharSequence constraint) {
|
protected FilterResults performFiltering(CharSequence constraint) {
|
||||||
FilterResults results = new FilterResults();
|
FilterResults results = new FilterResults();
|
||||||
List<String> resultCategories = categoryClient.searchCategories(constraint.toString(), 10).blockingGet();
|
List<CategoryItem> resultCategories = categoryClient
|
||||||
results.values = resultCategories;
|
.searchCategories(constraint.toString(), 10).blockingGet();
|
||||||
|
final List<String> namesOfCommonsCategories = new ArrayList<>();
|
||||||
|
for (final CategoryItem category :
|
||||||
|
resultCategories) {
|
||||||
|
namesOfCommonsCategories.add(category.getName());
|
||||||
|
}
|
||||||
|
results.values = namesOfCommonsCategories;
|
||||||
results.count = resultCategories.size();
|
results.count = resultCategories.size();
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,11 @@ public interface CategoryInterface {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GET("w/api.php?action=query&format=json&formatversion=2"
|
@GET("w/api.php?action=query&format=json&formatversion=2"
|
||||||
+ "&generator=search&gsrnamespace=14")
|
+ "&generator=search&prop=description|pageimages&piprop=thumbnail&pithumbsize=70"
|
||||||
|
+ "&gsrnamespace=14")
|
||||||
Single<MwQueryResponse> searchCategories(@Query("gsrsearch") String filter,
|
Single<MwQueryResponse> searchCategories(@Query("gsrsearch") String filter,
|
||||||
@Query("gsrlimit") int itemLimit, @Query("gsroffset") int offset);
|
@Query("gsrlimit") int itemLimit,
|
||||||
|
@Query("gsroffset") int offset);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Searches for categories starting with the specified prefix.
|
* Searches for categories starting with the specified prefix.
|
||||||
|
|
@ -32,9 +34,11 @@ public interface CategoryInterface {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@GET("w/api.php?action=query&format=json&formatversion=2"
|
@GET("w/api.php?action=query&format=json&formatversion=2"
|
||||||
+ "&generator=allcategories&prop=categoryinfo")
|
+ "&generator=allcategories&prop=categoryinfo|description|pageimages&piprop=thumbnail"
|
||||||
|
+ "&pithumbsize=70")
|
||||||
Single<MwQueryResponse> searchCategoriesForPrefix(@Query("gacprefix") String prefix,
|
Single<MwQueryResponse> searchCategoriesForPrefix(@Query("gacprefix") String prefix,
|
||||||
@Query("gaclimit") int itemLimit, @Query("gacoffset") int offset);
|
@Query("gaclimit") int itemLimit,
|
||||||
|
@Query("gacoffset") int offset);
|
||||||
|
|
||||||
@GET("w/api.php?action=query&format=json&formatversion=2"
|
@GET("w/api.php?action=query&format=json&formatversion=2"
|
||||||
+ "&generator=categorymembers&gcmtype=subcat"
|
+ "&generator=categorymembers&gcmtype=subcat"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,8 @@ import android.os.Parcelable
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
data class CategoryItem(val name: String, var isSelected: Boolean) : Parcelable {
|
data class CategoryItem(val name: String, val description: String,
|
||||||
|
val thumbnail: String, var isSelected: Boolean) : Parcelable {
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return "CategoryItem: '$name'"
|
return "CategoryItem: '$name'"
|
||||||
|
|
|
||||||
|
|
@ -250,8 +250,10 @@ public class NetworkingModule {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
public CategoryInterface provideCategoryInterface(@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
|
public CategoryInterface provideCategoryInterface(
|
||||||
return ServiceFactory.get(commonsWikiSite, BuildConfig.COMMONS_URL, CategoryInterface.class);
|
@Named(NAMED_COMMONS_WIKI_SITE) WikiSite commonsWikiSite) {
|
||||||
|
return ServiceFactory
|
||||||
|
.get(commonsWikiSite, BuildConfig.COMMONS_URL, CategoryInterface.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@ class PageableParentCategoriesDataSource @Inject constructor(
|
||||||
if (startPosition == 0) {
|
if (startPosition == 0) {
|
||||||
categoryClient.resetParentCategoryContinuation(query)
|
categoryClient.resetParentCategoryContinuation(query)
|
||||||
}
|
}
|
||||||
categoryClient.getParentCategoryList(query).blockingGet()
|
categoryClient.getParentCategoryList(query).blockingGet().map { it.name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,5 +12,6 @@ class PageableSearchCategoriesDataSource @Inject constructor(
|
||||||
|
|
||||||
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
override val loadFunction = { loadSize: Int, startPosition: Int ->
|
||||||
categoryClient.searchCategories(query, loadSize, startPosition).blockingGet()
|
categoryClient.searchCategories(query, loadSize, startPosition).blockingGet()
|
||||||
|
.map { it.name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,6 @@ class PageableSubCategoriesDataSource @Inject constructor(
|
||||||
if (startPosition == 0) {
|
if (startPosition == 0) {
|
||||||
categoryClient.resetSubCategoryContinuation(query)
|
categoryClient.resetSubCategoryContinuation(query)
|
||||||
}
|
}
|
||||||
categoryClient.getSubCategoryList(query).blockingGet()
|
categoryClient.getSubCategoryList(query).blockingGet().map { it.name }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.mwapi;
|
||||||
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_PREFIX;
|
import static fr.free.nrw.commons.category.CategoryClientKt.CATEGORY_PREFIX;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
@ -40,7 +41,7 @@ public class CategoryApi {
|
||||||
this.gson = gson;
|
this.gson = gson;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Single<List<String>> request(String coords) {
|
public Single<List<CategoryItem>> request(String coords) {
|
||||||
return Single.fromCallable(() -> {
|
return Single.fromCallable(() -> {
|
||||||
HttpUrl apiUrl = buildUrl(coords);
|
HttpUrl apiUrl = buildUrl(coords);
|
||||||
Timber.d("URL: %s", apiUrl.toString());
|
Timber.d("URL: %s", apiUrl.toString());
|
||||||
|
|
@ -53,12 +54,12 @@ public class CategoryApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
MwQueryResponse apiResponse = gson.fromJson(body.charStream(), MwQueryResponse.class);
|
MwQueryResponse apiResponse = gson.fromJson(body.charStream(), MwQueryResponse.class);
|
||||||
Set<String> categories = new LinkedHashSet<>();
|
Set<CategoryItem> categories = new LinkedHashSet<>();
|
||||||
if (apiResponse != null && apiResponse.query() != null && apiResponse.query().pages() != null) {
|
if (apiResponse != null && apiResponse.query() != null && apiResponse.query().pages() != null) {
|
||||||
for (MwQueryPage page : apiResponse.query().pages()) {
|
for (MwQueryPage page : apiResponse.query().pages()) {
|
||||||
if (page.categories() != null) {
|
if (page.categories() != null) {
|
||||||
for (MwQueryPage.Category category : page.categories()) {
|
for (MwQueryPage.Category category : page.categories()) {
|
||||||
categories.add(category.title().replace(CATEGORY_PREFIX, ""));
|
categories.add(new CategoryItem(category.title().replace(CATEGORY_PREFIX, ""), "", "", false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,19 @@
|
||||||
package fr.free.nrw.commons.upload
|
package fr.free.nrw.commons.upload
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import io.reactivex.subjects.BehaviorSubject
|
import io.reactivex.subjects.BehaviorSubject
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class GpsCategoryModel @Inject constructor() {
|
class GpsCategoryModel @Inject constructor() {
|
||||||
val categoriesFromLocation = BehaviorSubject.createDefault(emptyList<String>())
|
val categoriesFromLocation = BehaviorSubject.createDefault(emptyList<CategoryItem>())
|
||||||
|
|
||||||
fun clear() {
|
fun clear() {
|
||||||
categoriesFromLocation.onNext(emptyList())
|
categoriesFromLocation.onNext(emptyList())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setCategoriesFromLocation(categoryList: List<String>) {
|
fun setCategoriesFromLocation(categoryList: List<CategoryItem>) {
|
||||||
categoriesFromLocation.onNext(categoryList)
|
categoriesFromLocation.onNext(categoryList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package fr.free.nrw.commons.upload.categories
|
package fr.free.nrw.commons.upload.categories
|
||||||
|
|
||||||
import fr.free.nrw.commons.category.CategoryItem
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
|
import org.jetbrains.annotations.NotNull
|
||||||
|
|
||||||
class UploadCategoryAdapter(onCategoryClicked: (CategoryItem) -> Unit) :
|
class UploadCategoryAdapter(
|
||||||
|
onCategoryClicked: @NotNull() (CategoryItem) -> Unit) :
|
||||||
BaseDelegateAdapter<CategoryItem>(
|
BaseDelegateAdapter<CategoryItem>(
|
||||||
uploadCategoryDelegate(onCategoryClicked),
|
uploadCategoryDelegate(onCategoryClicked),
|
||||||
areItemsTheSame = { oldItem, newItem -> oldItem.name == newItem.name },
|
areItemsTheSame = { oldItem, newItem -> oldItem.name == newItem.name },
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,38 @@
|
||||||
package fr.free.nrw.commons.upload.categories
|
package fr.free.nrw.commons.upload.categories
|
||||||
|
|
||||||
|
import android.view.View
|
||||||
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||||
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.category.CategoryItem
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.databinding.LayoutUploadCategoriesItemBinding
|
import fr.free.nrw.commons.databinding.LayoutUploadCategoriesItemBinding
|
||||||
|
|
||||||
fun uploadCategoryDelegate(onCategoryClicked: (CategoryItem) -> Unit) =
|
fun uploadCategoryDelegate(onCategoryClicked: (CategoryItem) -> Unit) =
|
||||||
adapterDelegateViewBinding<CategoryItem, CategoryItem, LayoutUploadCategoriesItemBinding>({ layoutInflater, root ->
|
adapterDelegateViewBinding<CategoryItem, CategoryItem,
|
||||||
|
LayoutUploadCategoriesItemBinding>({ layoutInflater, root ->
|
||||||
LayoutUploadCategoriesItemBinding.inflate(layoutInflater, root, false)
|
LayoutUploadCategoriesItemBinding.inflate(layoutInflater, root, false)
|
||||||
}) {
|
}) {
|
||||||
binding.root.setOnClickListener {
|
val onClickListener = { _: View? ->
|
||||||
item.isSelected = !item.isSelected
|
item.isSelected = !item.isSelected
|
||||||
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
||||||
onCategoryClicked(item)
|
onCategoryClicked(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.root.setOnClickListener(onClickListener)
|
||||||
|
binding.uploadCategoryCheckbox.setOnClickListener(onClickListener)
|
||||||
|
|
||||||
bind {
|
bind {
|
||||||
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
binding.uploadCategoryCheckbox.isChecked = item.isSelected
|
||||||
binding.uploadCategoryCheckbox.text = item.name
|
binding.categoryLabel.text = item.name
|
||||||
|
if(item.thumbnail != "null") {
|
||||||
|
binding.categoryImage.setImageURI(item.thumbnail)
|
||||||
|
} else {
|
||||||
|
binding.categoryImage.setActualImageResource(R.drawable.commons)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item.description != "null") {
|
||||||
|
binding.categoryDescription.text = item.description
|
||||||
|
} else {
|
||||||
|
binding.categoryDescription.text = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package fr.free.nrw.commons.upload.structure.depictions
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.room.Entity
|
import androidx.room.Entity
|
||||||
import androidx.room.PrimaryKey
|
import androidx.room.PrimaryKey
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.nearby.Place
|
import fr.free.nrw.commons.nearby.Place
|
||||||
import fr.free.nrw.commons.upload.WikidataItem
|
import fr.free.nrw.commons.upload.WikidataItem
|
||||||
import fr.free.nrw.commons.wikidata.WikidataProperties
|
import fr.free.nrw.commons.wikidata.WikidataProperties
|
||||||
|
|
@ -28,7 +29,7 @@ data class DepictedItem constructor(
|
||||||
val description: String?,
|
val description: String?,
|
||||||
val imageUrl: String?,
|
val imageUrl: String?,
|
||||||
val instanceOfs: List<String>,
|
val instanceOfs: List<String>,
|
||||||
val commonsCategories: List<String>,
|
val commonsCategories: List<CategoryItem>,
|
||||||
var isSelected: Boolean,
|
var isSelected: Boolean,
|
||||||
@PrimaryKey override val id: String
|
@PrimaryKey override val id: String
|
||||||
) : WikidataItem, Parcelable {
|
) : WikidataItem, Parcelable {
|
||||||
|
|
@ -52,7 +53,8 @@ data class DepictedItem constructor(
|
||||||
getImageUrl(it.value, THUMB_IMAGE_SIZE)
|
getImageUrl(it.value, THUMB_IMAGE_SIZE)
|
||||||
},
|
},
|
||||||
entity[INSTANCE_OF].toIds(),
|
entity[INSTANCE_OF].toIds(),
|
||||||
entity[COMMONS_CATEGORY]?.map { (it.mainSnak.dataValue as DataValue.ValueString).value }
|
entity[COMMONS_CATEGORY]?.map { CategoryItem((it.mainSnak.dataValue as DataValue.ValueString).value,
|
||||||
|
"", "", false) }
|
||||||
?: emptyList(),
|
?: emptyList(),
|
||||||
false,
|
false,
|
||||||
entity.id()
|
entity.id()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package fr.free.nrw.commons.utils;
|
package fr.free.nrw.commons.utils;
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
|
||||||
public class StringSortingUtils {
|
public class StringSortingUtils {
|
||||||
|
|
@ -16,10 +17,10 @@ public class StringSortingUtils {
|
||||||
* @param filter String to compare similarity with
|
* @param filter String to compare similarity with
|
||||||
* @return Comparator with string similarity
|
* @return Comparator with string similarity
|
||||||
*/
|
*/
|
||||||
public static Comparator<String> sortBySimilarity(final String filter) {
|
public static Comparator<CategoryItem> sortBySimilarity(final String filter) {
|
||||||
return (firstItem, secondItem) -> {
|
return (firstItem, secondItem) -> {
|
||||||
double firstItemSimilarity = calculateSimilarity(firstItem, filter);
|
double firstItemSimilarity = calculateSimilarity(firstItem.getName(), filter);
|
||||||
double secondItemSimilarity = calculateSimilarity(secondItem, filter);
|
double secondItemSimilarity = calculateSimilarity(secondItem.getName(), filter);
|
||||||
return (int) Math.signum(secondItemSimilarity - firstItemSimilarity);
|
return (int) Math.signum(secondItemSimilarity - firstItemSimilarity);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,55 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<CheckBox xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:id="@+id/uploadCategoryCheckbox"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/category_layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/upload_category_checkbox"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:checkMark="?android:attr/textCheckMark"
|
android:checkMark="?android:attr/textCheckMark"
|
||||||
android:checked="false"
|
android:checked="false"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:padding="@dimen/tiny_gap"/>
|
android:padding="@dimen/tiny_gap"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/category_image"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<com.facebook.drawee.view.SimpleDraweeView
|
||||||
|
android:id="@+id/category_image"
|
||||||
|
android:layout_width="50dp"
|
||||||
|
android:layout_height="50dp"
|
||||||
|
android:paddingEnd="@dimen/tiny_gap"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintLeft_toRightOf="@+id/upload_category_checkbox"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
app:placeholderImage="@drawable/commons" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/category_image"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/category_label"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="@string/label"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/category_description"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
tools:text="@string/description" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -652,6 +652,8 @@ Upload your first media by tapping on the add button.</string>
|
||||||
The shadow of the image view of the location picker</string>
|
The shadow of the image view of the location picker</string>
|
||||||
<string name="image_location">Image Location</string>
|
<string name="image_location">Image Location</string>
|
||||||
<string name="check_whether_location_is_correct">Check whether location is correct</string>
|
<string name="check_whether_location_is_correct">Check whether location is correct</string>
|
||||||
|
<string name="label">Label</string>
|
||||||
|
<string name="description">Description</string>
|
||||||
<string name="title_page_bookmarks_items">Items</string>
|
<string name="title_page_bookmarks_items">Items</string>
|
||||||
<string name="custom_selector_title">Custom Selector</string>
|
<string name="custom_selector_title">Custom Selector</string>
|
||||||
<string name="custom_selector_empty_text">No Images</string>
|
<string name="custom_selector_empty_text">No Images</string>
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ fun depictedItem(
|
||||||
description: String = "desc",
|
description: String = "desc",
|
||||||
imageUrl: String = "",
|
imageUrl: String = "",
|
||||||
instanceOfs: List<String> = listOf(),
|
instanceOfs: List<String> = listOf(),
|
||||||
commonsCategories: List<String> = listOf(),
|
commonsCategories: List<CategoryItem> = listOf(),
|
||||||
isSelected: Boolean = false,
|
isSelected: Boolean = false,
|
||||||
id: String = "entityId"
|
id: String = "entityId"
|
||||||
) = DepictedItem(
|
) = DepictedItem(
|
||||||
|
|
@ -29,8 +29,9 @@ fun depictedItem(
|
||||||
id = id
|
id = id
|
||||||
)
|
)
|
||||||
|
|
||||||
fun categoryItem(name: String = "name", selected: Boolean = false) =
|
fun categoryItem(name: String = "name", description: String = "desc",
|
||||||
CategoryItem(name, selected)
|
thumbUrl: String = "thumbUrl", selected: Boolean = false) =
|
||||||
|
CategoryItem(name, description, thumbUrl, selected)
|
||||||
|
|
||||||
fun media(
|
fun media(
|
||||||
thumbUrl: String? = "thumbUrl",
|
thumbUrl: String? = "thumbUrl",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
package fr.free.nrw.commons.bookmarks.items
|
package fr.free.nrw.commons.bookmarks.items
|
||||||
|
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
|
@ -33,7 +34,8 @@ class BookmarkItemsControllerTest {
|
||||||
list.add(
|
list.add(
|
||||||
DepictedItem(
|
DepictedItem(
|
||||||
"name", "description", "image url", listOf("instance"),
|
"name", "description", "image url", listOf("instance"),
|
||||||
listOf("categories"), true, "id")
|
listOf(CategoryItem("category name", "category description",
|
||||||
|
"category thumbnail", false)), true, "id")
|
||||||
)
|
)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import android.os.RemoteException
|
||||||
import com.nhaarman.mockitokotlin2.*
|
import com.nhaarman.mockitokotlin2.*
|
||||||
import fr.free.nrw.commons.TestCommonsApplication
|
import fr.free.nrw.commons.TestCommonsApplication
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.*
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsDao.Table.*
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
|
|
@ -26,7 +27,9 @@ class BookmarkItemsDaoTest {
|
||||||
COLUMN_DESCRIPTION,
|
COLUMN_DESCRIPTION,
|
||||||
COLUMN_IMAGE,
|
COLUMN_IMAGE,
|
||||||
COLUMN_INSTANCE_LIST,
|
COLUMN_INSTANCE_LIST,
|
||||||
COLUMN_CATEGORIES_LIST,
|
COLUMN_CATEGORIES_NAME_LIST,
|
||||||
|
COLUMN_CATEGORIES_DESCRIPTION_LIST,
|
||||||
|
COLUMN_CATEGORIES_THUMBNAIL_LIST,
|
||||||
COLUMN_IS_SELECTED,
|
COLUMN_IS_SELECTED,
|
||||||
COLUMN_ID,
|
COLUMN_ID,
|
||||||
)
|
)
|
||||||
|
|
@ -43,7 +46,10 @@ class BookmarkItemsDaoTest {
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
exampleItemBookmark = DepictedItem("itemName", "itemDescription",
|
exampleItemBookmark = DepictedItem("itemName", "itemDescription",
|
||||||
"itemImageUrl", listOf("instance"), listOf("categories"), false,
|
"itemImageUrl", listOf("instance"), listOf(
|
||||||
|
CategoryItem("category name", "category description",
|
||||||
|
"category thumbnail", false)
|
||||||
|
), false,
|
||||||
"itemID")
|
"itemID")
|
||||||
testObject = BookmarkItemsDao { client }
|
testObject = BookmarkItemsDao { client }
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +78,9 @@ class BookmarkItemsDaoTest {
|
||||||
Assert.assertEquals("itemDescription", it.description)
|
Assert.assertEquals("itemDescription", it.description)
|
||||||
Assert.assertEquals("itemImageUrl", it.imageUrl)
|
Assert.assertEquals("itemImageUrl", it.imageUrl)
|
||||||
Assert.assertEquals(listOf("instance"), it.instanceOfs)
|
Assert.assertEquals(listOf("instance"), it.instanceOfs)
|
||||||
Assert.assertEquals(listOf("categories"), it.commonsCategories)
|
Assert.assertEquals(listOf(CategoryItem("category name",
|
||||||
|
"category description",
|
||||||
|
"category thumbnail", false)), it.commonsCategories)
|
||||||
Assert.assertEquals(false, it.isSelected)
|
Assert.assertEquals(false, it.isSelected)
|
||||||
Assert.assertEquals("itemID", it.id)
|
Assert.assertEquals("itemID", it.id)
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +139,7 @@ class BookmarkItemsDaoTest {
|
||||||
Assert.assertTrue(testObject.updateBookmarkItem(exampleItemBookmark))
|
Assert.assertTrue(testObject.updateBookmarkItem(exampleItemBookmark))
|
||||||
verify(client).insert(eq(BookmarkItemsContentProvider.BASE_URI), captor.capture())
|
verify(client).insert(eq(BookmarkItemsContentProvider.BASE_URI), captor.capture())
|
||||||
captor.firstValue.let { cv ->
|
captor.firstValue.let { cv ->
|
||||||
Assert.assertEquals(7, cv.size())
|
Assert.assertEquals(9, cv.size())
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
exampleItemBookmark.name,
|
exampleItemBookmark.name,
|
||||||
cv.getAsString(COLUMN_NAME)
|
cv.getAsString(COLUMN_NAME)
|
||||||
|
|
@ -149,8 +157,16 @@ class BookmarkItemsDaoTest {
|
||||||
cv.getAsString(COLUMN_INSTANCE_LIST)
|
cv.getAsString(COLUMN_INSTANCE_LIST)
|
||||||
)
|
)
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
exampleItemBookmark.commonsCategories[0],
|
exampleItemBookmark.commonsCategories[0].name,
|
||||||
cv.getAsString(COLUMN_CATEGORIES_LIST)
|
cv.getAsString(COLUMN_CATEGORIES_NAME_LIST)
|
||||||
|
)
|
||||||
|
Assert.assertEquals(
|
||||||
|
exampleItemBookmark.commonsCategories[0].description,
|
||||||
|
cv.getAsString(COLUMN_CATEGORIES_DESCRIPTION_LIST)
|
||||||
|
)
|
||||||
|
Assert.assertEquals(
|
||||||
|
exampleItemBookmark.commonsCategories[0].thumbnail,
|
||||||
|
cv.getAsString(COLUMN_CATEGORIES_THUMBNAIL_LIST)
|
||||||
)
|
)
|
||||||
Assert.assertEquals(
|
Assert.assertEquals(
|
||||||
exampleItemBookmark.isSelected,
|
exampleItemBookmark.isSelected,
|
||||||
|
|
@ -263,8 +279,8 @@ class BookmarkItemsDaoTest {
|
||||||
|
|
||||||
for (i in 0 until rowCount) {
|
for (i in 0 until rowCount) {
|
||||||
addRow(listOf("itemName", "itemDescription",
|
addRow(listOf("itemName", "itemDescription",
|
||||||
"itemImageUrl", "instance", "categories", false,
|
"itemImageUrl", "instance", "category name", "category description",
|
||||||
"itemID"))
|
"category thumbnail", false, "itemID"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,6 +14,7 @@ import com.nhaarman.mockitokotlin2.whenever
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.TestAppAdapter
|
import fr.free.nrw.commons.TestAppAdapter
|
||||||
import fr.free.nrw.commons.TestCommonsApplication
|
import fr.free.nrw.commons.TestCommonsApplication
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.profile.ProfileActivity
|
import fr.free.nrw.commons.profile.ProfileActivity
|
||||||
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
import fr.free.nrw.commons.upload.structure.depictions.DepictedItem
|
||||||
import org.junit.Assert
|
import org.junit.Assert
|
||||||
|
|
@ -62,7 +63,10 @@ class BookmarkItemsFragmentUnitTest {
|
||||||
list.add(
|
list.add(
|
||||||
DepictedItem(
|
DepictedItem(
|
||||||
"name", "description", "image url", listOf("instance"),
|
"name", "description", "image url", listOf("instance"),
|
||||||
listOf("categories"), true, "id")
|
listOf(
|
||||||
|
CategoryItem("category name", "category description",
|
||||||
|
"category thumbnail", false)
|
||||||
|
), true, "id")
|
||||||
)
|
)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,8 @@ class CategoriesModelTest {
|
||||||
fun searchAllFoundCaseTest() {
|
fun searchAllFoundCaseTest() {
|
||||||
val categoriesModel = CategoriesModel(categoryClient, mock(), mock())
|
val categoriesModel = CategoriesModel(categoryClient, mock(), mock())
|
||||||
|
|
||||||
val expectedList = listOf("Test")
|
val expectedList = listOf(CategoryItem(
|
||||||
|
"Test", "", "", false))
|
||||||
whenever(
|
whenever(
|
||||||
categoryClient.searchCategoriesForPrefix(
|
categoryClient.searchCategoriesForPrefix(
|
||||||
ArgumentMatchers.anyString(),
|
ArgumentMatchers.anyString(),
|
||||||
|
|
@ -45,7 +46,8 @@ class CategoriesModelTest {
|
||||||
.thenReturn(Single.just(expectedList))
|
.thenReturn(Single.just(expectedList))
|
||||||
|
|
||||||
// Checking if both return "Test"
|
// Checking if both return "Test"
|
||||||
val expectedItems = expectedList.map { CategoryItem(it, false) }
|
val expectedItems = expectedList.map { CategoryItem(
|
||||||
|
it.name, it.description, it.thumbnail, false) }
|
||||||
var categoryTerm = "Test"
|
var categoryTerm = "Test"
|
||||||
categoriesModel.searchAll(categoryTerm, emptyList(), emptyList())
|
categoriesModel.searchAll(categoryTerm, emptyList(), emptyList())
|
||||||
.test()
|
.test()
|
||||||
|
|
@ -65,10 +67,12 @@ class CategoriesModelTest {
|
||||||
@Test
|
@Test
|
||||||
fun `searchAll with empty search terms creates results from gps, title search & recents`() {
|
fun `searchAll with empty search terms creates results from gps, title search & recents`() {
|
||||||
val gpsCategoryModel: GpsCategoryModel = mock()
|
val gpsCategoryModel: GpsCategoryModel = mock()
|
||||||
val depictedItem = depictedItem(commonsCategories = listOf("depictionCategory"))
|
val depictedItem = depictedItem(commonsCategories = listOf(CategoryItem(
|
||||||
|
"depictionCategory", "", "", false)))
|
||||||
|
|
||||||
whenever(gpsCategoryModel.categoriesFromLocation)
|
whenever(gpsCategoryModel.categoriesFromLocation)
|
||||||
.thenReturn(BehaviorSubject.createDefault(listOf("gpsCategory")))
|
.thenReturn(BehaviorSubject.createDefault(listOf(CategoryItem(
|
||||||
|
"gpsCategory", "", "", false))))
|
||||||
whenever(
|
whenever(
|
||||||
categoryClient.searchCategories(
|
categoryClient.searchCategories(
|
||||||
ArgumentMatchers.anyString(),
|
ArgumentMatchers.anyString(),
|
||||||
|
|
@ -76,8 +80,10 @@ class CategoriesModelTest {
|
||||||
ArgumentMatchers.anyInt()
|
ArgumentMatchers.anyInt()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.thenReturn(Single.just(listOf("titleSearch")))
|
.thenReturn(Single.just(listOf(CategoryItem(
|
||||||
whenever(categoryDao.recentCategories(25)).thenReturn(listOf("recentCategories"))
|
"titleSearch", "", "", false))))
|
||||||
|
whenever(categoryDao.recentCategories(25)).thenReturn(listOf(CategoryItem(
|
||||||
|
"recentCategories","","", false)))
|
||||||
val imageTitleList = listOf("Test")
|
val imageTitleList = listOf("Test")
|
||||||
CategoriesModel(categoryClient, categoryDao, gpsCategoryModel)
|
CategoriesModel(categoryClient, categoryDao, gpsCategoryModel)
|
||||||
.searchAll("", imageTitleList, listOf(depictedItem))
|
.searchAll("", imageTitleList, listOf(depictedItem))
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ class CategoryClientTest {
|
||||||
.thenReturn(Single.just(mockResponse))
|
.thenReturn(Single.just(mockResponse))
|
||||||
categoryClient.searchCategories("tes", 10)
|
categoryClient.searchCategories("tes", 10)
|
||||||
.test()
|
.test()
|
||||||
.assertValues(listOf("Test"))
|
.assertValues(listOf(CategoryItem("Test", "", "", false)))
|
||||||
categoryClient.searchCategories("tes", 10, 10)
|
categoryClient.searchCategories("tes", 10, 10)
|
||||||
.test()
|
.test()
|
||||||
.assertValues(listOf("Test"))
|
.assertValues(listOf(CategoryItem("Test", "", "", false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -59,10 +59,10 @@ class CategoryClientTest {
|
||||||
.thenReturn(Single.just(mockResponse))
|
.thenReturn(Single.just(mockResponse))
|
||||||
categoryClient.searchCategoriesForPrefix("tes", 10)
|
categoryClient.searchCategoriesForPrefix("tes", 10)
|
||||||
.test()
|
.test()
|
||||||
.assertValues(listOf("Test"))
|
.assertValues(listOf(CategoryItem("Test", "", "", false)))
|
||||||
categoryClient.searchCategoriesForPrefix("tes", 10, 10)
|
categoryClient.searchCategoriesForPrefix("tes", 10, 10)
|
||||||
.test()
|
.test()
|
||||||
.assertValues(listOf("Test"))
|
.assertValues(listOf(CategoryItem("Test", "", "", false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -84,7 +84,7 @@ class CategoryClientTest {
|
||||||
.thenReturn(Single.just(mockResponse))
|
.thenReturn(Single.just(mockResponse))
|
||||||
categoryClient.getParentCategoryList("tes")
|
categoryClient.getParentCategoryList("tes")
|
||||||
.test()
|
.test()
|
||||||
.assertValues(listOf("Test"))
|
.assertValues(listOf(CategoryItem("Test", "", "", false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -104,7 +104,7 @@ class CategoryClientTest {
|
||||||
.thenReturn(Single.just(mockResponse))
|
.thenReturn(Single.just(mockResponse))
|
||||||
categoryClient.getSubCategoryList("tes")
|
categoryClient.getSubCategoryList("tes")
|
||||||
.test()
|
.test()
|
||||||
.assertValues(listOf("Test"))
|
.assertValues(listOf(CategoryItem("Test", "", "", false)))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,8 @@ import java.util.*
|
||||||
@Config(sdk = [21], application = TestCommonsApplication::class)
|
@Config(sdk = [21], application = TestCommonsApplication::class)
|
||||||
class CategoryDaoTest {
|
class CategoryDaoTest {
|
||||||
|
|
||||||
private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_LAST_USED, COLUMN_TIMES_USED)
|
private val columns = arrayOf(COLUMN_ID, COLUMN_NAME, COLUMN_DESCRIPTION,
|
||||||
|
COLUMN_THUMBNAIL, COLUMN_LAST_USED, COLUMN_TIMES_USED)
|
||||||
private val client: ContentProviderClient = mock()
|
private val client: ContentProviderClient = mock()
|
||||||
private val database: SQLiteDatabase = mock()
|
private val database: SQLiteDatabase = mock()
|
||||||
private val captor = argumentCaptor<ContentValues>()
|
private val captor = argumentCaptor<ContentValues>()
|
||||||
|
|
@ -122,8 +123,10 @@ class CategoryDaoTest {
|
||||||
|
|
||||||
verify(client).update(eq(category.contentUri), captor.capture(), isNull(), isNull())
|
verify(client).update(eq(category.contentUri), captor.capture(), isNull(), isNull())
|
||||||
captor.firstValue.let { cv ->
|
captor.firstValue.let { cv ->
|
||||||
assertEquals(3, cv.size())
|
assertEquals(5, cv.size())
|
||||||
assertEquals(category.name, cv.getAsString(COLUMN_NAME))
|
assertEquals(category.name, cv.getAsString(COLUMN_NAME))
|
||||||
|
assertEquals(category.description, cv.getAsString(COLUMN_DESCRIPTION))
|
||||||
|
assertEquals(category.thumbnail, cv.getAsString(COLUMN_THUMBNAIL))
|
||||||
assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED))
|
assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED))
|
||||||
assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED))
|
assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED))
|
||||||
}
|
}
|
||||||
|
|
@ -134,14 +137,17 @@ class CategoryDaoTest {
|
||||||
fun saveNewCategory() {
|
fun saveNewCategory() {
|
||||||
val contentUri = CategoryContentProvider.uriForId(111)
|
val contentUri = CategoryContentProvider.uriForId(111)
|
||||||
whenever(client.insert(isA(), isA())).thenReturn(contentUri)
|
whenever(client.insert(isA(), isA())).thenReturn(contentUri)
|
||||||
val category = Category(null, "showImageWithItem", Date(234L), 1)
|
val category = Category(null, "showImageWithItem", "description",
|
||||||
|
"image", Date(234L), 1)
|
||||||
|
|
||||||
testObject.save(category)
|
testObject.save(category)
|
||||||
|
|
||||||
verify(client).insert(eq(BASE_URI), captor.capture())
|
verify(client).insert(eq(BASE_URI), captor.capture())
|
||||||
captor.firstValue.let { cv ->
|
captor.firstValue.let { cv ->
|
||||||
assertEquals(3, cv.size())
|
assertEquals(5, cv.size())
|
||||||
assertEquals(category.name, cv.getAsString(COLUMN_NAME))
|
assertEquals(category.name, cv.getAsString(COLUMN_NAME))
|
||||||
|
assertEquals(category.description, cv.getAsString(COLUMN_DESCRIPTION))
|
||||||
|
assertEquals(category.thumbnail, cv.getAsString(COLUMN_THUMBNAIL))
|
||||||
assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED))
|
assertEquals(category.lastUsed.time, cv.getAsLong(COLUMN_LAST_USED))
|
||||||
assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED))
|
assertEquals(category.timesUsed, cv.getAsInteger(COLUMN_TIMES_USED))
|
||||||
assertEquals(contentUri, category.contentUri)
|
assertEquals(contentUri, category.contentUri)
|
||||||
|
|
@ -186,6 +192,8 @@ class CategoryDaoTest {
|
||||||
|
|
||||||
assertEquals(uriForId(1), category?.contentUri)
|
assertEquals(uriForId(1), category?.contentUri)
|
||||||
assertEquals("showImageWithItem", category?.name)
|
assertEquals("showImageWithItem", category?.name)
|
||||||
|
assertEquals("description", category?.description)
|
||||||
|
assertEquals("image", category?.thumbnail)
|
||||||
assertEquals(123L, category?.lastUsed?.time)
|
assertEquals(123L, category?.lastUsed?.time)
|
||||||
assertEquals(2, category?.timesUsed)
|
assertEquals(2, category?.timesUsed)
|
||||||
|
|
||||||
|
|
@ -241,7 +249,7 @@ class CategoryDaoTest {
|
||||||
val result = testObject.recentCategories(10)
|
val result = testObject.recentCategories(10)
|
||||||
|
|
||||||
assertEquals(1, result.size)
|
assertEquals(1, result.size)
|
||||||
assertEquals("showImageWithItem", result[0])
|
assertEquals("showImageWithItem", result[0].name)
|
||||||
|
|
||||||
verify(client).query(
|
verify(client).query(
|
||||||
eq(BASE_URI),
|
eq(BASE_URI),
|
||||||
|
|
@ -264,7 +272,7 @@ class CategoryDaoTest {
|
||||||
|
|
||||||
private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply {
|
private fun createCursor(rowCount: Int) = MatrixCursor(columns, rowCount).apply {
|
||||||
for (i in 0 until rowCount) {
|
for (i in 0 until rowCount) {
|
||||||
addRow(listOf("1", "showImageWithItem", "123", "2"))
|
addRow(listOf("1", "showImageWithItem", "description", "image", "123", "2"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -67,13 +67,15 @@ class CategoriesPresenterTest {
|
||||||
)
|
)
|
||||||
whenever(repository.containsYear("selected")).thenReturn(false)
|
whenever(repository.containsYear("selected")).thenReturn(false)
|
||||||
whenever(repository.containsYear("doesContainYear")).thenReturn(true)
|
whenever(repository.containsYear("doesContainYear")).thenReturn(true)
|
||||||
whenever(repository.selectedCategories).thenReturn(listOf(categoryItem("selected", true)))
|
whenever(repository.selectedCategories).thenReturn(listOf(
|
||||||
|
categoryItem("selected", "", "",true)))
|
||||||
categoriesPresenter.searchForCategories("test")
|
categoriesPresenter.searchForCategories("test")
|
||||||
testScheduler.triggerActions()
|
testScheduler.triggerActions()
|
||||||
verify(view).showProgress(true)
|
verify(view).showProgress(true)
|
||||||
verify(view).showError(null)
|
verify(view).showError(null)
|
||||||
verify(view).setCategories(null)
|
verify(view).setCategories(null)
|
||||||
verify(view).setCategories(listOf(categoryItem("selected", true)))
|
verify(view).setCategories(listOf(
|
||||||
|
categoryItem("selected", "", "", true)))
|
||||||
verify(view).showProgress(false)
|
verify(view).showProgress(false)
|
||||||
verifyNoMoreInteractions(view)
|
verifyNoMoreInteractions(view)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package fr.free.nrw.commons.upload
|
package fr.free.nrw.commons.upload
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
||||||
|
|
@ -18,7 +19,8 @@ class GpsCategoryModelTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `setCategoriesFromLocation emits the new value`() {
|
fun `setCategoriesFromLocation emits the new value`() {
|
||||||
val expectedList = listOf("category")
|
val expectedList = listOf(
|
||||||
|
CategoryItem("category", "", "", false))
|
||||||
gpsCategoryModel.categoriesFromLocation.test()
|
gpsCategoryModel.categoriesFromLocation.test()
|
||||||
.also { gpsCategoryModel.setCategoriesFromLocation(expectedList) }
|
.also { gpsCategoryModel.setCategoriesFromLocation(expectedList) }
|
||||||
.assertValues(emptyList(), expectedList)
|
.assertValues(emptyList(), expectedList)
|
||||||
|
|
|
||||||
|
|
@ -110,7 +110,7 @@ class DepictedItemTest {
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
).commonsCategories,
|
).commonsCategories.map { it.name },
|
||||||
listOf("1", "2"))
|
listOf("1", "2"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
package fr.free.nrw.commons.utils
|
package fr.free.nrw.commons.utils
|
||||||
|
|
||||||
|
import fr.free.nrw.commons.category.CategoryItem
|
||||||
import fr.free.nrw.commons.utils.StringSortingUtils.sortBySimilarity
|
import fr.free.nrw.commons.utils.StringSortingUtils.sortBySimilarity
|
||||||
import org.junit.Assert.assertEquals
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
|
|
@ -9,8 +10,18 @@ class StringSortingUtilsTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSortingNumbersBySimilarity() {
|
fun testSortingNumbersBySimilarity() {
|
||||||
val actualList = listOf("1234567", "4567", "12345", "123", "1234")
|
val actualList = listOf(
|
||||||
val expectedList = listOf("1234", "12345", "123", "1234567", "4567")
|
CategoryItem("1234567", "", "", false),
|
||||||
|
CategoryItem("4567", "", "", false),
|
||||||
|
CategoryItem("12345", "", "", false),
|
||||||
|
CategoryItem("123", "", "", false),
|
||||||
|
CategoryItem("1234", "", "", false))
|
||||||
|
val expectedList = listOf(
|
||||||
|
CategoryItem("1234", "", "", false),
|
||||||
|
CategoryItem("12345", "", "", false),
|
||||||
|
CategoryItem("123", "", "", false),
|
||||||
|
CategoryItem("1234567", "", "", false),
|
||||||
|
CategoryItem("4567", "", "", false))
|
||||||
|
|
||||||
sort(actualList, sortBySimilarity("1234"))
|
sort(actualList, sortBySimilarity("1234"))
|
||||||
|
|
||||||
|
|
@ -20,22 +31,22 @@ class StringSortingUtilsTest {
|
||||||
@Test
|
@Test
|
||||||
fun testSortingTextBySimilarity() {
|
fun testSortingTextBySimilarity() {
|
||||||
val actualList = listOf(
|
val actualList = listOf(
|
||||||
"The quick brown fox",
|
CategoryItem("The quick brown fox", "", "", false),
|
||||||
"quick brown fox",
|
CategoryItem("quick brown fox", "", "", false),
|
||||||
"The",
|
CategoryItem("The", "", "", false),
|
||||||
"The quick ",
|
CategoryItem("The quick ", "", "", false),
|
||||||
"The fox",
|
CategoryItem("The fox", "", "", false),
|
||||||
"brown fox",
|
CategoryItem("brown fox", "", "", false),
|
||||||
"fox"
|
CategoryItem("fox", "", "", false)
|
||||||
)
|
)
|
||||||
val expectedList = listOf(
|
val expectedList = listOf(
|
||||||
"The",
|
CategoryItem("The", "", "", false),
|
||||||
"The fox",
|
CategoryItem("The fox", "", "", false),
|
||||||
"The quick ",
|
CategoryItem("The quick ", "", "", false),
|
||||||
"The quick brown fox",
|
CategoryItem("The quick brown fox", "", "", false),
|
||||||
"quick brown fox",
|
CategoryItem("quick brown fox", "", "", false),
|
||||||
"brown fox",
|
CategoryItem("brown fox", "", "", false),
|
||||||
"fox"
|
CategoryItem("fox", "", "", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
sort(actualList, sortBySimilarity("The"))
|
sort(actualList, sortBySimilarity("The"))
|
||||||
|
|
@ -46,18 +57,18 @@ class StringSortingUtilsTest {
|
||||||
@Test
|
@Test
|
||||||
fun testSortingSymbolsBySimilarity() {
|
fun testSortingSymbolsBySimilarity() {
|
||||||
val actualList = listOf(
|
val actualList = listOf(
|
||||||
"$$$$$",
|
CategoryItem("$$$$$", "", "", false),
|
||||||
"****",
|
CategoryItem("****", "", "", false),
|
||||||
"**$*",
|
CategoryItem("**$*", "", "", false),
|
||||||
"*$*$",
|
CategoryItem("*$*$", "", "", false),
|
||||||
".*$"
|
CategoryItem(".*$", "", "", false)
|
||||||
)
|
)
|
||||||
val expectedList = listOf(
|
val expectedList = listOf(
|
||||||
"**$*",
|
CategoryItem("**$*", "", "", false),
|
||||||
"*$*$",
|
CategoryItem("*$*$", "", "", false),
|
||||||
".*$",
|
CategoryItem(".*$", "", "", false),
|
||||||
"****",
|
CategoryItem("****", "", "", false),
|
||||||
"$$$$$"
|
CategoryItem("$$$$$", "", "", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
sort(actualList, sortBySimilarity("**$"))
|
sort(actualList, sortBySimilarity("**$"))
|
||||||
|
|
@ -69,25 +80,25 @@ class StringSortingUtilsTest {
|
||||||
fun testSortingMixedStringsBySimilarity() {
|
fun testSortingMixedStringsBySimilarity() {
|
||||||
// Sample from Category:2018 Android phones
|
// Sample from Category:2018 Android phones
|
||||||
val actualList = listOf(
|
val actualList = listOf(
|
||||||
"ASUS ZenFone 5 (2018)",
|
CategoryItem("ASUS ZenFone 5 (2018)", "", "", false),
|
||||||
"Google Pixel 3",
|
CategoryItem("Google Pixel 3", "", "", false),
|
||||||
"HTC U12",
|
CategoryItem("HTC U12", "", "", false),
|
||||||
"Huawei P20",
|
CategoryItem("Huawei P20", "", "", false),
|
||||||
"LG G7 ThinQ",
|
CategoryItem("LG G7 ThinQ", "", "", false),
|
||||||
"Samsung Galaxy A8 (2018)",
|
CategoryItem("Samsung Galaxy A8 (2018)", "", "", false),
|
||||||
"Samsung Galaxy S9",
|
CategoryItem("Samsung Galaxy S9", "", "", false),
|
||||||
// One with more complicated symbols
|
// One with more complicated symbols
|
||||||
"MadeUpPhone 2018.$£#你好"
|
CategoryItem("MadeUpPhone 2018.$£#你好", "", "", false)
|
||||||
)
|
)
|
||||||
val expectedList = listOf(
|
val expectedList = listOf(
|
||||||
"Samsung Galaxy S9",
|
CategoryItem("Samsung Galaxy S9", "", "", false),
|
||||||
"ASUS ZenFone 5 (2018)",
|
CategoryItem("ASUS ZenFone 5 (2018)", "", "", false),
|
||||||
"Samsung Galaxy A8 (2018)",
|
CategoryItem("Samsung Galaxy A8 (2018)", "", "", false),
|
||||||
"Google Pixel 3",
|
CategoryItem("Google Pixel 3", "", "", false),
|
||||||
"HTC U12",
|
CategoryItem("HTC U12", "", "", false),
|
||||||
"Huawei P20",
|
CategoryItem("Huawei P20", "", "", false),
|
||||||
"LG G7 ThinQ",
|
CategoryItem("LG G7 ThinQ", "", "", false),
|
||||||
"MadeUpPhone 2018.$£#你好"
|
CategoryItem("MadeUpPhone 2018.$£#你好", "", "", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
sort(actualList, sortBySimilarity("S9"))
|
sort(actualList, sortBySimilarity("S9"))
|
||||||
|
|
@ -98,26 +109,26 @@ class StringSortingUtilsTest {
|
||||||
@Test
|
@Test
|
||||||
fun testSortingWithEmptyStrings() {
|
fun testSortingWithEmptyStrings() {
|
||||||
val actualList = listOf(
|
val actualList = listOf(
|
||||||
"brown fox",
|
CategoryItem("brown fox", "", "", false),
|
||||||
"",
|
CategoryItem("", "", "", false),
|
||||||
"quick brown fox",
|
CategoryItem("quick brown fox", "", "", false),
|
||||||
"the",
|
CategoryItem("the", "", "", false),
|
||||||
"",
|
CategoryItem("", "", "", false),
|
||||||
"the fox",
|
CategoryItem("the fox", "", "", false),
|
||||||
"fox",
|
CategoryItem("fox", "", "", false),
|
||||||
"",
|
CategoryItem("", "", "", false),
|
||||||
""
|
CategoryItem("", "", "", false)
|
||||||
)
|
)
|
||||||
val expectedList = listOf(
|
val expectedList = listOf(
|
||||||
"the fox",
|
CategoryItem("the fox", "", "", false),
|
||||||
"brown fox",
|
CategoryItem("brown fox", "", "", false),
|
||||||
"the",
|
CategoryItem("the", "", "", false),
|
||||||
"fox",
|
CategoryItem("fox", "", "", false),
|
||||||
"quick brown fox",
|
CategoryItem("quick brown fox", "", "", false),
|
||||||
"",
|
CategoryItem("", "", "", false),
|
||||||
"",
|
CategoryItem("", "", "", false),
|
||||||
"",
|
CategoryItem("", "", "", false),
|
||||||
""
|
CategoryItem("", "", "", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
sort(actualList, sortBySimilarity("the fox"))
|
sort(actualList, sortBySimilarity("the fox"))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue