diff --git a/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java b/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java index a470d163f..e9163cc6b 100644 --- a/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java +++ b/app/src/main/java/fr/free/nrw/commons/repository/UploadRepository.java @@ -19,8 +19,11 @@ import io.reactivex.Flowable; import io.reactivex.Observable; import io.reactivex.Single; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Locale; +import java.util.Set; import javax.inject.Inject; import javax.inject.Singleton; @@ -254,6 +257,23 @@ public class UploadRepository { return depictModel.searchAllEntities(query); } + /** + * Gets the depiction for each unique {@link Place} associated with an {@link UploadItem} + * from {@link #getUploads()} + * + * @return a single that provides the depictions + */ + public Single> getPlaceDepictions() { + final Set places = new HashSet<>(); + for (final UploadItem item : getUploads()) { + final Place place = item.getPlace(); + if (place != null) { + places.add(place); + } + } + return depictModel.getPlaceDepictions(new ArrayList<>(places)); + } + /** * Returns nearest place matching the passed latitude and longitude * @param decLatitude diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsContract.java b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsContract.java index 5f215c3ad..0184744f8 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsContract.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsContract.java @@ -60,6 +60,11 @@ public interface DepictsContract { */ void searchForDepictions(String query); + /** + * Selects all associated places (if any) as depictions + */ + void selectPlaceDepictions(); + /** * Check if depictions were selected * from the depiction list diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.java b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.java index 8b53d95a1..0b1dc5156 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsFragment.java @@ -100,6 +100,14 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra depictsRecyclerView.setAdapter(adapter); } + @Override + protected void onBecameVisible() { + super.onBecameVisible(); + // Select Place depiction as the fragment becomes visible to ensure that the most up to date + // Place is used (i.e. if the user accepts a nearby place dialog) + presenter.selectPlaceDepictions(); + } + @Override public void goToNextScreen() { callback.onNextButtonClicked(callback.getIndexInViewFlipper(this)); @@ -146,6 +154,7 @@ public class DepictsFragment extends UploadBaseFragment implements DepictsContra @Override public void setDepictsList(List depictedItemList) { adapter.setItems(depictedItemList); + depictsRecyclerView.smoothScrollToPosition(0); } @OnClick(R.id.depicts_next) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt index a273aa57f..388dfeccf 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/DepictsPresenter.kt @@ -84,6 +84,35 @@ class DepictsPresenter @Inject constructor( compositeDisposable.clear() } + /** + * Selects the place depictions retrieved by the repository + */ + override fun selectPlaceDepictions() { + compositeDisposable.add(repository.placeDepictions + .subscribeOn(ioScheduler) + .observeOn(mainThreadScheduler) + .subscribe(::selectNewDepictions) + ) + } + + /** + * Selects each [DepictedItem] in a given list as if they were clicked by the user by calling + * [onDepictItemClicked] for each depiction and adding the depictions to [depictedItems] + */ + private fun selectNewDepictions(toSelect: List) { + toSelect.forEach { + it.isSelected = true + repository.onDepictItemClicked(it) + } + + // Add the new selections to the list of depicted items so that the selections appear + // immediately (i.e. without any search term queries) + depictedItems.value?.toMutableList() + ?.let { toSelect + it } + ?.distinctBy(DepictedItem::id) + ?.let { depictedItems.value = it } + } + override fun onPreviousButtonClicked() { view.goToPreviousScreen() } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/depicts/UploadDepictsAdapter.kt b/app/src/main/java/fr/free/nrw/commons/upload/depicts/UploadDepictsAdapter.kt index a3a843afa..d2c1bca7b 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/depicts/UploadDepictsAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/depicts/UploadDepictsAdapter.kt @@ -6,5 +6,6 @@ import fr.free.nrw.commons.upload.structure.depictions.DepictedItem class UploadDepictsAdapter(onDepictsClicked: (DepictedItem) -> Unit) : BaseDelegateAdapter( uploadDepictsDelegate(onDepictsClicked), - areItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id } + areItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id }, + areContentsTheSame = { itemA, itemB -> itemA.isSelected == itemB.isSelected} ) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictModel.kt b/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictModel.kt index f2d48d5d6..6e4157c23 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictModel.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictModel.kt @@ -3,6 +3,7 @@ package fr.free.nrw.commons.upload.structure.depictions import fr.free.nrw.commons.explore.depictions.DepictsClient import fr.free.nrw.commons.nearby.Place import io.reactivex.Flowable +import io.reactivex.Observable import io.reactivex.Single import io.reactivex.processors.BehaviorProcessor import timber.log.Timber @@ -27,19 +28,29 @@ class DepictModel @Inject constructor(private val depictsClient: DepictsClient) fun searchAllEntities(query: String): Flowable> { return if (query.isBlank()) nearbyPlaces.switchMap { places: List -> - depictsClient.getEntities(places.toIds()) - .map { - it.entities() - .values - .mapIndexed { index, entity -> DepictedItem(entity, places[index]) } - } - .onErrorResumeWithEmptyList() - .toFlowable() + getPlaceDepictions(places).toFlowable() } else networkItems(query) } + /** + * Provides [DepictedItem] instances via a [Single] for a given list of [Place], providing an + * empty list if no places are provided or if there is an error + */ + fun getPlaceDepictions(places: List): Single> = + places.toIds().let { ids -> + if (ids.isNotEmpty()) + depictsClient.getEntities(ids) + .map{ + it.entities() + .values + .mapIndexed { index, entity -> DepictedItem(entity, places[index])} + } + .onErrorResumeWithEmptyList() + else Single.just(emptyList()) + } + private fun networkItems(query: String): Flowable> { return depictsClient.searchForDepictions(query, SEARCH_DEPICTS_LIMIT, 0) .onErrorResumeWithEmptyList() diff --git a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java index 633dc1818..e37dd7cf1 100644 --- a/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java +++ b/app/src/main/java/fr/free/nrw/commons/wikidata/WikidataEditService.java @@ -206,12 +206,7 @@ public class WikidataEditService { } private Observable depictionEdits(Contribution contribution, Long fileEntityId) { - final ArrayList depictedItems = new ArrayList<>(contribution.getDepictedItems()); - final WikidataPlace wikidataPlace = contribution.getWikidataPlace(); - if (wikidataPlace != null) { - depictedItems.add(wikidataPlace); - } - return Observable.fromIterable(depictedItems) + return Observable.fromIterable(contribution.getDepictedItems()) .concatMap(wikidataItem -> addDepictsProperty(fileEntityId.toString(), wikidataItem)); } }