diff --git a/README.md b/README.md index 06210d055..765935148 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Initially started by the Wikimedia Foundation, this app is now maintained by gra ## Documentation -We try to have an extensive documentation at [our wiki here at Github][4]: +We try to have an extensive documentation at our [documentation repository][4]: * [User Documentation][5] * [Contributor Documentation][6] @@ -45,11 +45,11 @@ This software is open source, licensed under the [Apache License 2.0][10]. [2]: https://commons-app.github.io/ [3]: https://github.com/commons-app/apps-android-commons/issues -[4]: https://github.com/commons-app/apps-android-commons/wiki -[5]: https://github.com/commons-app/apps-android-commons/wiki#user-documentation -[6]: https://github.com/commons-app/apps-android-commons/wiki#contributor-documentation -[7]: https://github.com/commons-app/apps-android-commons/wiki/Volunteers-welcome%21 -[8]: https://github.com/commons-app/apps-android-commons/wiki#developer-documentation -[9]: https://github.com/commons-app/apps-android-commons/wiki/Libraries-used +[4]: https://github.com/commons-app/commons-app-documentation/blob/master/android/README.md#-android-documentation +[5]: https://github.com/commons-app/commons-app-documentation/blob/master/android/README.md#-user-documentation +[6]: https://github.com/commons-app/commons-app-documentation/blob/master/android/README.md#️-contributor-documentation +[7]: https://github.com/commons-app/commons-app-documentation/blob/master/android/Volunteers-welcome!.md#volunteers-welcome +[8]: https://github.com/commons-app/commons-app-documentation/blob/master/android/README.md#-developer-documentation +[9]: https://github.com/commons-app/commons-app-documentation/blob/master/android/Libraries-used.md#libraries-used [10]: https://www.apache.org/licenses/LICENSE-2.0 diff --git a/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.java b/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.java index b9c10496c..9d3bde848 100644 --- a/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.java +++ b/app/src/main/java/fr/free/nrw/commons/OkHttpConnectionFactory.java @@ -1,11 +1,6 @@ package fr.free.nrw.commons; import androidx.annotation.NonNull; - -import okhttp3.logging.HttpLoggingInterceptor.Level; -import org.wikipedia.dataclient.SharedPreferenceCookieManager; -import org.wikipedia.dataclient.okhttp.HttpStatusException; - import java.io.File; import java.io.IOException; import okhttp3.Cache; diff --git a/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java b/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java index 3efef06d4..4b9fe4b55 100644 --- a/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java +++ b/app/src/main/java/fr/free/nrw/commons/bookmarks/locations/BookmarkLocationsDao.java @@ -9,6 +9,7 @@ import android.os.RemoteException; import androidx.annotation.NonNull; +import fr.free.nrw.commons.nearby.NearbyController; import java.util.ArrayList; import java.util.List; @@ -74,8 +75,10 @@ public class BookmarkLocationsDao { boolean bookmarkExists = findBookmarkLocation(bookmarkLocation); if (bookmarkExists) { deleteBookmarkLocation(bookmarkLocation); + NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, false); } else { addBookmarkLocation(bookmarkLocation); + NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, true); } return !bookmarkExists; } @@ -160,10 +163,9 @@ public class BookmarkLocationsDao { location, cursor.getString(cursor.getColumnIndex(Table.COLUMN_CATEGORY)), builder.build(), - null, - null + cursor.getString(cursor.getColumnIndex(Table.COLUMN_PIC)), + cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESTROYED)) ); - // TODO: add pic and destroyed to bookmark location dao } private ContentValues toContentValues(Place bookmarkLocation) { @@ -179,6 +181,7 @@ public class BookmarkLocationsDao { cv.put(BookmarkLocationsDao.Table.COLUMN_LAT, bookmarkLocation.location.getLatitude()); cv.put(BookmarkLocationsDao.Table.COLUMN_LONG, bookmarkLocation.location.getLongitude()); cv.put(BookmarkLocationsDao.Table.COLUMN_PIC, bookmarkLocation.pic); + cv.put(BookmarkLocationsDao.Table.COLUMN_DESTROYED, bookmarkLocation.destroyed); return cv; } @@ -197,6 +200,7 @@ public class BookmarkLocationsDao { static final String COLUMN_WIKIDATA_LINK = "location_wikidata_link"; static final String COLUMN_COMMONS_LINK = "location_commons_link"; static final String COLUMN_PIC = "location_pic"; + static final String COLUMN_DESTROYED = "location_destroyed"; // NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES. public static final String[] ALL_FIELDS = { @@ -211,7 +215,8 @@ public class BookmarkLocationsDao { COLUMN_WIKIPEDIA_LINK, COLUMN_WIKIDATA_LINK, COLUMN_COMMONS_LINK, - COLUMN_PIC + COLUMN_PIC, + COLUMN_DESTROYED }; static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME; @@ -228,7 +233,8 @@ public class BookmarkLocationsDao { + COLUMN_WIKIPEDIA_LINK + " STRING," + COLUMN_WIKIDATA_LINK + " STRING," + COLUMN_COMMONS_LINK + " STRING," - + COLUMN_PIC + " STRING" + + COLUMN_PIC + " STRING," + + COLUMN_DESTROYED + " STRING" + ");"; public static void onCreate(SQLiteDatabase db) { @@ -242,37 +248,24 @@ public class BookmarkLocationsDao { public static void onUpdate(SQLiteDatabase db, int from, int to) { Timber.d("bookmarksLocations db is updated from:"+from+", to:"+to); - if (from == to) { - return; - } - if (from < 7) { - // doesn't exist yet - from++; - onUpdate(db, from, to); - return; - } - if (from == 7) { - // table added in version 8 - onCreate(db); - from++; - onUpdate(db, from, to); - return; - } - if (from == 8) { - from++; - onUpdate(db, from, to); - return; - } - if (from == 10 && to == 11) { - from++; - //This is safe, and can be called clean, as we/I do not remember the appropriate version for this - //We are anyways switching to room, these things won't be nescessary then - try { - db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;"); - }catch (SQLiteException exception){ - Timber.e(exception);// - } - return; + switch (from) { + case 7: onCreate(db); + case 8: // No change + case 9: // No change + case 10: + try { + db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;"); + } catch (SQLiteException exception){ + Timber.e(exception); + } + case 11: // No change + case 12: + try { + db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_destroyed STRING;"); + }catch (SQLiteException exception){ + Timber.e(exception); + } + break; } } } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.kt b/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.kt index ae2d0b0fd..48ac1fc7c 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.kt +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoriesModel.kt @@ -2,9 +2,10 @@ package fr.free.nrw.commons.category import android.text.TextUtils import fr.free.nrw.commons.upload.GpsCategoryModel +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem import fr.free.nrw.commons.utils.StringSortingUtils import io.reactivex.Observable -import io.reactivex.functions.Function3 +import io.reactivex.functions.Function4 import timber.log.Timber import java.util.* import javax.inject.Inject @@ -67,30 +68,42 @@ class CategoriesModel @Inject constructor( * @param imageTitleList * @return */ - fun searchAll(term: String, imageTitleList: List): Observable> { - return suggestionsOrSearch(term, imageTitleList) + fun searchAll( + term: String, + imageTitleList: List, + selectedDepictions: List + ): Observable> { + return suggestionsOrSearch(term, imageTitleList, selectedDepictions) .map { it.map { CategoryItem(it, false) } } } - private fun suggestionsOrSearch(term: String, imageTitleList: List): - Observable> { + private fun suggestionsOrSearch( + term: String, + imageTitleList: List, + selectedDepictions: List + ): Observable> { return if (TextUtils.isEmpty(term)) Observable.combineLatest( + categoriesFromDepiction(selectedDepictions), gpsCategoryModel.categoriesFromLocation, titleCategories(imageTitleList), Observable.just(categoryDao.recentCategories(SEARCH_CATS_LIMIT)), - Function3(::combine) + Function4(::combine) ) else categoryClient.searchCategoriesForPrefix(term.toLowerCase(), SEARCH_CATS_LIMIT) .map { it.sortedWith(StringSortingUtils.sortBySimilarity(term)) } } + private fun categoriesFromDepiction(selectedDepictions: List) = + Observable.just(selectedDepictions.map { it.commonsCategories }.flatten()) + private fun combine( + depictionCategories: List, locationCategories: List, titles: List, recents: List - ) = locationCategories + titles + recents + ) = depictionCategories + locationCategories + titles + recents /** @@ -98,14 +111,13 @@ class CategoriesModel @Inject constructor( * @param titleList * @return */ - private fun titleCategories(titleList: List): Observable> { - return if (titleList.isNotEmpty()) + private fun titleCategories(titleList: List) = + if (titleList.isNotEmpty()) Observable.combineLatest(titleList.map { getTitleCategories(it) }) { searchResults -> searchResults.map { it as List }.flatten() } else Observable.just(emptyList()) - } /** * Return category for single title diff --git a/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java b/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java index b678d0491..7921e930f 100644 --- a/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java +++ b/app/src/main/java/fr/free/nrw/commons/data/DBOpenHelper.java @@ -13,7 +13,7 @@ import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao; public class DBOpenHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "commons.db"; - private static final int DATABASE_VERSION = 12; + private static final int DATABASE_VERSION = 13; public static final String CONTRIBUTIONS_TABLE = "contributions"; private final String DROP_TABLE_STATEMENT="DROP TABLE IF EXISTS %s"; diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.java b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.java index 67e59390c..d79757ecd 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.java +++ b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.java @@ -90,8 +90,9 @@ public interface DepictedImagesContract { /** * Fetches more images for the item and adds it to the grid view adapter + * @param entityId */ - void fetchMoreImages(); + void fetchMoreImages(String entityId); /** * fetch captions for the image using filename and replace title of on the image thumbnail(if captions are available) diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.java b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.java index 1c1aeaef3..6e3c128d3 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.java @@ -136,7 +136,7 @@ public class DepictedImagesFragment extends DaggerFragment implements DepictedIm if (!NetworkUtils.isInternetConnectionEstablished(getContext())) { handleNoInternet(); } else { - presenter.fetchMoreImages(); + presenter.fetchMoreImages(entityId); } } if (isLastPage) { diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.java b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.java index 18bace3ab..02707b652 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.java @@ -80,10 +80,11 @@ public class DepictedImagesPresenter implements DepictedImagesContract.UserActio /** * Fetches more images for the item and adds it to the grid view adapter + * @param entityId */ @SuppressLint("CheckResult") @Override - public void fetchMoreImages() { + public void fetchMoreImages(String entityId) { view.progressBarVisible(true); compositeDisposable.add(depictsClient.fetchImagesForDepictedItem(entityId, queryList.size()) .subscribeOn(ioScheduler) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapter.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapter.kt index 8310915a1..f50e41764 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapter.kt @@ -4,10 +4,11 @@ import android.view.View import android.view.ViewGroup import androidx.paging.PagedListAdapter import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.RecyclerView import fr.free.nrw.commons.R -import fr.free.nrw.commons.explore.BaseViewHolder import fr.free.nrw.commons.explore.inflate import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.item_depictions.* @@ -22,18 +23,17 @@ class DepictionAdapter(val onDepictionClicked: (DepictedItem) -> Unit) : } ) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DepictedItemViewHolder { - return DepictedItemViewHolder(parent.inflate(R.layout.item_depictions), onDepictionClicked) + return DepictedItemViewHolder(parent.inflate(R.layout.item_depictions)) } override fun onBindViewHolder(holder: DepictedItemViewHolder, position: Int) { - holder.bind(getItem(position)!!) + holder.bind(getItem(position)!!, onDepictionClicked) } } -class DepictedItemViewHolder(containerView: View, val onDepictionClicked: (DepictedItem) -> Unit) : - BaseViewHolder(containerView) { - - override fun bind(item: DepictedItem) { +class DepictedItemViewHolder(override val containerView: View) : + RecyclerView.ViewHolder(containerView), LayoutContainer { + fun bind(item: DepictedItem, onDepictionClicked: (DepictedItem) -> Unit) { containerView.setOnClickListener { onDepictionClicked(item) } depicts_label.text = item.name description.text = item.description @@ -44,7 +44,3 @@ class DepictedItemViewHolder(containerView: View, val onDepictionClicked: (Depic } } } - - - - diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictsClient.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictsClient.kt index b363e44fc..183282d33 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictsClient.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictsClient.kt @@ -75,7 +75,7 @@ class DepictsClient @Inject constructor( } fun getEntities(ids: String): Single { - return depictsInterface.getEntities(ids, Locale.getDefault().language) + return depictsInterface.getEntities(ids) } fun toDepictions(sparqlResponse: Observable): Observable> { diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/FooterAdapter.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/FooterAdapter.kt new file mode 100644 index 000000000..76d4be40a --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/FooterAdapter.kt @@ -0,0 +1,54 @@ +package fr.free.nrw.commons.explore.depictions + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.annotation.LayoutRes +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter +import androidx.recyclerview.widget.RecyclerView +import fr.free.nrw.commons.R +import kotlinx.android.extensions.LayoutContainer +import kotlinx.android.synthetic.main.list_item_load_more.* + +class FooterAdapter(private val onRefreshClicked: () -> Unit) : + ListAdapter(object : + DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: FooterItem, newItem: FooterItem) = oldItem == newItem + + override fun areContentsTheSame(oldItem: FooterItem, newItem: FooterItem) = + oldItem == newItem + }) { + + override fun getItemViewType(position: Int): Int { + return getItem(position).ordinal + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = + when (FooterItem.values()[viewType]) { + FooterItem.LoadingItem -> LoadingViewHolder(parent.inflate(R.layout.list_item_progress)) + FooterItem.RefreshItem -> RefreshViewHolder( + parent.inflate(R.layout.list_item_load_more), + onRefreshClicked + ) + } + + override fun onBindViewHolder(holder: FooterViewHolder, position: Int) {} +} + +open class FooterViewHolder(override val containerView: View) : + RecyclerView.ViewHolder(containerView), + LayoutContainer + +class LoadingViewHolder(containerView: View) : FooterViewHolder(containerView) +class RefreshViewHolder(containerView: View, onRefreshClicked: () -> Unit) : + FooterViewHolder(containerView) { + init { + listItemLoadMoreButton.setOnClickListener { onRefreshClicked() } + } +} + +enum class FooterItem { LoadingItem, RefreshItem } + +fun ViewGroup.inflate(@LayoutRes layoutId: Int, attachToRoot: Boolean = false): View = + LayoutInflater.from(context).inflate(layoutId, this, attachToRoot) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSource.kt new file mode 100644 index 000000000..413ee017e --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSource.kt @@ -0,0 +1,63 @@ +package fr.free.nrw.commons.explore.depictions + +import androidx.paging.PositionalDataSource +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import io.reactivex.Completable +import io.reactivex.processors.PublishProcessor +import io.reactivex.schedulers.Schedulers +import timber.log.Timber + + +data class SearchDepictionsDataSource constructor( + private val depictsClient: DepictsClient, + private val loadingStates: PublishProcessor, + private val query: String +) : PositionalDataSource() { + + private var lastExecutedRequest: (() -> Boolean)? = null + + override fun loadInitial( + params: LoadInitialParams, + callback: LoadInitialCallback + ) { + storeAndExecute { + loadingStates.offer(LoadingState.InitialLoad) + performWithTryCatch { + callback.onResult( + getItems(query, params.requestedLoadSize, params.requestedStartPosition), + params.requestedStartPosition + ) + } + } + } + + override fun loadRange(params: LoadRangeParams, callback: LoadRangeCallback) { + storeAndExecute { + loadingStates.offer(LoadingState.Loading) + performWithTryCatch { + callback.onResult(getItems(query, params.loadSize, params.startPosition)) + } + } + } + + fun retryFailedRequest() { + Completable.fromAction { lastExecutedRequest?.invoke() } + .subscribeOn(Schedulers.io()) + .subscribe() + } + + private fun getItems(query: String, limit: Int, offset: Int) = + depictsClient.searchForDepictions(query, limit, offset).blockingGet() + + private fun storeAndExecute(function: () -> Boolean) { + function.also { lastExecutedRequest = it }.invoke() + } + + private fun performWithTryCatch(function: () -> Unit) = try { + function.invoke() + loadingStates.offer(LoadingState.Complete) + } catch (e: Exception) { + Timber.e(e) + loadingStates.offer(LoadingState.Error) + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactory.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactory.kt new file mode 100644 index 000000000..90bdcdc40 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactory.kt @@ -0,0 +1,88 @@ +package fr.free.nrw.commons.explore.depictions + +import androidx.lifecycle.LiveData +import androidx.paging.Config +import androidx.paging.DataSource +import androidx.paging.PagedList +import androidx.paging.toLiveData +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import io.reactivex.Flowable +import io.reactivex.processors.PublishProcessor +import javax.inject.Inject + +private const val PAGE_SIZE = 50 +private const val INITIAL_LOAD_SIZE = 50 + +class SearchableDepictionsDataSourceFactory @Inject constructor( + val searchDepictionsDataSourceFactoryFactory: SearchDepictionsDataSourceFactoryFactory, + val liveDataConverter: LiveDataConverter +) { + private val _loadingStates = PublishProcessor.create() + val loadingStates: Flowable = _loadingStates + private val _searchResults = PublishProcessor.create>>() + val searchResults: Flowable>> = _searchResults + private val _noItemsLoadedEvent = PublishProcessor.create() + val noItemsLoadedEvent: Flowable = _noItemsLoadedEvent + + private var currentFactory: SearchDepictionsDataSourceFactory? = null + + fun onQueryUpdated(query: String) { + _searchResults.offer( + liveDataConverter.convert( + searchDepictionsDataSourceFactoryFactory.create(query, _loadingStates) + .also { currentFactory = it } + ) { _noItemsLoadedEvent.offer(Unit) } + ) + } + + fun retryFailedRequest() { + currentFactory?.retryFailedRequest() + } +} + +class LiveDataConverter @Inject constructor() { + fun convert( + dataSourceFactory: SearchDepictionsDataSourceFactory, + zeroItemsLoadedFunction: () -> Unit + ): LiveData> { + return dataSourceFactory.toLiveData( + Config( + pageSize = PAGE_SIZE, + initialLoadSizeHint = INITIAL_LOAD_SIZE, + enablePlaceholders = false + ), + boundaryCallback = object : PagedList.BoundaryCallback() { + override fun onZeroItemsLoaded() { + zeroItemsLoadedFunction() + } + } + ) + } + +} + +interface SearchDepictionsDataSourceFactoryFactory { + fun create(query: String, loadingStates: PublishProcessor) + : SearchDepictionsDataSourceFactory +} + +class SearchDepictionsDataSourceFactory constructor( + private val depictsClient: DepictsClient, + private val query: String, + private val loadingStates: PublishProcessor +) : DataSource.Factory() { + private var currentDataSource: SearchDepictionsDataSource? = null + override fun create() = SearchDepictionsDataSource(depictsClient, loadingStates, query) + .also { currentDataSource = it } + + fun retryFailedRequest() { + currentDataSource?.retryFailedRequest() + } +} + +sealed class LoadingState { + object InitialLoad : LoadingState() + object Loading : LoadingState() + object Complete : LoadingState() + object Error : LoadingState() +} diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaClient.java b/app/src/main/java/fr/free/nrw/commons/media/MediaClient.java index a6ba1897e..3bbe842b5 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaClient.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaClient.java @@ -171,7 +171,7 @@ public class MediaClient { * @return caption for image using wikibaseIdentifier */ public Single getCaptionByWikibaseIdentifier(String wikibaseIdentifier) { - return mediaDetailInterface.getCaptionForImage(Locale.getDefault().getLanguage(), wikibaseIdentifier) + return mediaDetailInterface.getEntityForImage(Locale.getDefault().getLanguage(), wikibaseIdentifier) .map(mediaDetailResponse -> { if (isSuccess(mediaDetailResponse)) { for (Entity wikibaseItem : mediaDetailResponse.entities().values()) { @@ -208,11 +208,15 @@ public class MediaClient { * @return label */ public Single getLabelForDepiction(String entityId, String language) { - return mediaDetailInterface.getEntity(entityId, language) + return mediaDetailInterface.getEntity(entityId) .map(entities -> { if (isSuccess(entities)) { for (Entity entity : entities.entities().values()) { - for (Label label : entity.labels().values()) { + final Map languageToLabelMap = entity.labels(); + if (languageToLabelMap.containsKey(language)) { + return languageToLabelMap.get(language).value(); + } + for (Label label : languageToLabelMap.values()) { return label.value(); } } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java index 34a637425..d78c0026b 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailFragment.java @@ -51,7 +51,6 @@ import fr.free.nrw.commons.delete.ReasonBuilder; import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.ui.widget.HtmlTextView; -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; import fr.free.nrw.commons.utils.ViewUtilWrapper; import io.reactivex.Single; import io.reactivex.android.schedulers.AndroidSchedulers; diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java index c972ccc12..f1e407f76 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailInterface.java @@ -20,12 +20,11 @@ public interface MediaDetailInterface { /** * Gets labels for Depictions using Entity Id from MediaWikiAPI + * @param entityId EntityId (Ex: Q81566) of the depict entity * - * @param entityId EntityId (Ex: Q81566) of the depict entity - * @param language user's locale */ @GET("/w/api.php?format=json&action=wbgetentities&props=labels&languagefallback=1") - Observable getEntity(@Query("ids") String entityId, @Query("languages") String language); + Observable getEntity(@Query("ids") String entityId); /** * Fetches caption using wikibaseIdentifier @@ -33,5 +32,5 @@ public interface MediaDetailInterface { * @param wikibaseIdentifier pageId for the media */ @GET("/w/api.php?action=wbgetentities&props=labels&format=json&languagefallback=1&sites=commonswiki") - Observable getCaptionForImage(@Query("languages") String language, @Query("ids") String wikibaseIdentifier); + Observable getEntityForImage(@Query("languages") String language, @Query("ids") String wikibaseIdentifier); } diff --git a/app/src/main/java/fr/free/nrw/commons/nearby/Label.java b/app/src/main/java/fr/free/nrw/commons/nearby/Label.java index ac939f5da..19c175fd8 100644 --- a/app/src/main/java/fr/free/nrw/commons/nearby/Label.java +++ b/app/src/main/java/fr/free/nrw/commons/nearby/Label.java @@ -4,7 +4,9 @@ import android.os.Parcel; import androidx.annotation.DrawableRes; +import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Map; import fr.free.nrw.commons.R; @@ -17,6 +19,7 @@ import fr.free.nrw.commons.R; */ public enum Label { + BOOKMARKS("BOOKMARK", R.drawable.ic_filled_star_24dp), BUILDING("Q41176", R.drawable.round_icon_generic_building), HOUSE("Q3947", R.drawable.round_icon_house), COTTAGE("Q5783996", R.drawable.round_icon_house), @@ -92,4 +95,8 @@ public enum Label { Label label = TEXT_TO_DESCRIPTION.get(text); return label == null ? UNKNOWN : label; } + + public static List