From 0e5ba98c2e3e71f53339cf134da9b98cebf9c18f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Se=C3=A1n=20Mac=20Gillicuddy?= Date: Thu, 25 Jun 2020 10:08:15 +0100 Subject: [PATCH] #3818 Convert SubDepictionListFragment to use Pagination (#3819) --- .../free/nrw/commons/ExploreActivityTest.kt | 4 +- app/src/main/AndroidManifest.xml | 4 +- .../free/nrw/commons/auth/LoginActivity.java | 2 +- .../nrw/commons/depictions/DepictionModule.kt | 23 --- .../Media/DepictedImagesContract.kt | 12 -- .../commons/depictions/models/Continue.java | 57 ------- .../nrw/commons/depictions/models/Query.java | 60 -------- .../nrw/commons/depictions/models/Search.java | 140 ----------------- .../commons/depictions/models/Searchinfo.java | 42 ----- .../subClass/SubDepictionAdapter.kt | 11 -- .../subClass/SubDepictionListContract.java | 32 ---- .../subClass/SubDepictionListFragment.java | 144 ------------------ .../subClass/SubDepictionListPresenter.java | 116 -------------- .../nrw/commons/di/ActivityBuilderModule.java | 4 +- .../di/CommonsApplicationComponent.java | 2 +- .../nrw/commons/di/FragmentBuilderModule.java | 16 +- .../{categories => }/ExploreActivity.java | 4 +- .../free/nrw/commons/explore/FooterAdapter.kt | 54 ------- .../nrw/commons/explore/SearchActivity.java | 2 +- .../SearchCategoriesFragmentPresenter.kt | 14 -- .../free/nrw/commons/explore/SearchModule.kt | 21 +-- .../PageableCategoriesDataSource.kt | 4 +- .../PagedSearchCategoriesAdapter.kt | 4 +- .../SearchCategoriesFragmentContract.kt | 8 - .../SearchCategoriesFragmentPresenterImpl.kt | 16 ++ .../categories/SearchCategoryFragment.kt | 6 +- .../explore/depictions/DepictionAdapter.kt | 2 +- .../depictions/DepictionAdapterDelegates.kt | 21 --- .../explore/depictions/DepictionModule.kt | 29 ++++ .../explore/depictions/DepictsClient.kt | 77 +--------- .../depictions/PageableDepictionsFragment.kt | 13 ++ .../depictions/SearchDepictionsDataSource.kt | 63 -------- .../depictions/SearchDepictionsFragment.kt | 27 ---- .../SearchDepictionsFragmentContract.kt | 12 -- .../SearchableDepictionsDataSourceFactory.kt | 88 ----------- .../WikidataItemDetailsActivity.java | 25 ++- .../child/ChildDepictionsFragment.kt | 24 +++ .../child/ChildDepictionsPresenterImpl.kt | 17 +++ .../PageableChildDepictionsDataSource.kt | 17 +++ .../media}/DepictedImagesFragment.kt | 8 +- .../media/DepictedImagesPresenterImpl.kt} | 11 +- .../media}/PageableDepictedMediaDataSource.kt | 8 +- .../PageableParentDepictionsDataSource.kt | 17 +++ .../parent/ParentDepictionsFragment.kt | 24 +++ .../parent/ParentDepictionsPresenterImpl.kt | 19 +++ .../PageableDepictionsDataSource.kt | 9 +- .../search/SearchDepictionsFragment.kt | 18 +++ .../SearchDepictionsFragmentPresenterImpl.kt} | 10 +- .../explore/media/PageableMediaDataSource.kt | 6 +- .../explore/media/PageableMediaFragment.kt | 2 +- .../explore/media/PagedMediaAdapter.kt | 4 +- .../explore/media/SearchMediaFragment.kt | 6 +- .../media/SearchMediaFragmentContract.kt | 10 -- ...kt => SearchMediaFragmentPresenterImpl.kt} | 9 +- .../{ => paging}/BasePagingFragment.kt | 2 +- .../{ => paging}/BasePagingPresenter.kt | 2 +- .../explore/{ => paging}/BaseViewHolder.kt | 2 +- .../{depictions => paging}/FooterAdapter.kt | 6 +- .../explore/{ => paging}/PagingContract.kt | 2 +- .../explore/{ => paging}/PagingDataSource.kt | 8 +- .../{ => paging}/PagingDataSourceFactory.kt | 18 ++- .../commons/media/MediaDetailFragment.java | 2 +- .../commons/mwapi/OkHttpJsonApiClient.java | 22 +-- .../models => mwapi}/SparqlResponses.kt | 6 +- .../commons/theme/NavigationBaseActivity.java | 2 +- .../structure/depictions/DepictedItem.kt | 44 +++++- .../res/layout/fragment_search_depictions.xml | 29 ---- app/src/main/res/xml/shortcuts.xml | 2 +- .../resources/queries/parentclasses_query.rq | 5 +- .../resources/queries/subclasses_query.rq | 5 +- .../SubDepictionListPresenterTest.kt | 70 --------- .../explore/BasePagingPresenterTest.kt | 1 + .../explore/PageableBaseDataSourceTest.kt | 5 +- .../explore/PagingDataSourceFactoryTest.kt | 7 +- ...aSourceTest.kt => PagingDataSourceTest.kt} | 14 +- .../PageableDepictionsDataSourceTest.kt | 9 +- .../SearchDepictionsDataSourceFactoryTest.kt | 53 ------- .../SearchDepictionsDataSourceTest.kt | 106 ------------- ...archableDepictionsDataSourceFactoryTest.kt | 80 ---------- .../PageableChildDepictionsDataSourceTest.kt | 35 +++++ .../PageableDepictedMediaDataSourceTest.kt | 2 +- .../PageableParentDepictionsDataSourceTest.kt | 37 +++++ 82 files changed, 474 insertions(+), 1480 deletions(-) delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/DepictionModule.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/models/Continue.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/models/Query.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/models/Search.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/models/Searchinfo.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionAdapter.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListContract.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListFragment.java delete mode 100644 app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListPresenter.java rename app/src/main/java/fr/free/nrw/commons/explore/{categories => }/ExploreActivity.java (98%) delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/FooterAdapter.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/SearchCategoriesFragmentPresenter.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentContract.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentPresenterImpl.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapterDelegates.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionModule.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsFragment.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSource.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragment.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentContract.kt delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactory.kt rename app/src/main/java/fr/free/nrw/commons/{ => explore}/depictions/WikidataItemDetailsActivity.java (87%) create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsFragment.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsPresenterImpl.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSource.kt rename app/src/main/java/fr/free/nrw/commons/{depictions/Media => explore/depictions/media}/DepictedImagesFragment.kt (72%) rename app/src/main/java/fr/free/nrw/commons/{depictions/Media/DepictedImagesPresenter.kt => explore/depictions/media/DepictedImagesPresenterImpl.kt} (56%) rename app/src/main/java/fr/free/nrw/commons/{depictions/Media => explore/depictions/media}/PageableDepictedMediaDataSource.kt (67%) create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSource.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsFragment.kt create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsPresenterImpl.kt rename app/src/main/java/fr/free/nrw/commons/explore/depictions/{ => search}/PageableDepictionsDataSource.kt (67%) create mode 100644 app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragment.kt rename app/src/main/java/fr/free/nrw/commons/explore/depictions/{SearchDepictionsFragmentPresenter.kt => search/SearchDepictionsFragmentPresenterImpl.kt} (57%) delete mode 100644 app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentContract.kt rename app/src/main/java/fr/free/nrw/commons/explore/media/{SearchMediaFragmentPresenter.kt => SearchMediaFragmentPresenterImpl.kt} (59%) rename app/src/main/java/fr/free/nrw/commons/explore/{ => paging}/BasePagingFragment.kt (98%) rename app/src/main/java/fr/free/nrw/commons/explore/{ => paging}/BasePagingPresenter.kt (97%) rename app/src/main/java/fr/free/nrw/commons/explore/{ => paging}/BaseViewHolder.kt (87%) rename app/src/main/java/fr/free/nrw/commons/explore/{depictions => paging}/FooterAdapter.kt (91%) rename app/src/main/java/fr/free/nrw/commons/explore/{ => paging}/PagingContract.kt (93%) rename app/src/main/java/fr/free/nrw/commons/explore/{ => paging}/PagingDataSource.kt (91%) rename app/src/main/java/fr/free/nrw/commons/explore/{ => paging}/PagingDataSourceFactory.kt (86%) rename app/src/main/java/fr/free/nrw/commons/{depictions/subClass/models => mwapi}/SparqlResponses.kt (62%) delete mode 100644 app/src/main/res/layout/fragment_search_depictions.xml delete mode 100644 app/src/test/kotlin/fr/free/nrw/commons/depictions/SubDepictionListPresenterTest.kt rename app/src/test/kotlin/fr/free/nrw/commons/explore/{SearchDataSourceTest.kt => PagingDataSourceTest.kt} (91%) delete mode 100644 app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceFactoryTest.kt delete mode 100644 app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceTest.kt delete mode 100644 app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactoryTest.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSourceTest.kt rename app/src/test/kotlin/fr/free/nrw/commons/{depictions/Media => explore/depictions/media}/PageableDepictedMediaDataSourceTest.kt (93%) create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSourceTest.kt diff --git a/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt b/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt index aba45f691..221d0fce9 100644 --- a/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt +++ b/app/src/androidTest/java/fr/free/nrw/commons/ExploreActivityTest.kt @@ -5,7 +5,7 @@ import androidx.test.runner.AndroidJUnit4 import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith -import fr.free.nrw.commons.explore.categories.ExploreActivity +import fr.free.nrw.commons.explore.ExploreActivity @RunWith(AndroidJUnit4::class) class ExploreActivityTest { @@ -16,4 +16,4 @@ class ExploreActivityTest { fun orientationChange() { UITestHelper.changeOrientation(activityRule) } -} \ No newline at end of file +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index da4f147c8..6f8eade2e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -118,12 +118,12 @@ android:parentActivityName=".contributions.MainActivity" /> diff --git a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java index ed1bd29c7..f2c552a83 100644 --- a/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/auth/LoginActivity.java @@ -51,7 +51,7 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.WelcomeActivity; import fr.free.nrw.commons.contributions.MainActivity; import fr.free.nrw.commons.di.ApplicationlessInjection; -import fr.free.nrw.commons.explore.categories.ExploreActivity; +import fr.free.nrw.commons.explore.ExploreActivity; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.theme.NavigationBaseActivity; import fr.free.nrw.commons.utils.ConfigUtils; diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/DepictionModule.kt b/app/src/main/java/fr/free/nrw/commons/depictions/DepictionModule.kt deleted file mode 100644 index 830c1b27d..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/DepictionModule.kt +++ /dev/null @@ -1,23 +0,0 @@ -package fr.free.nrw.commons.depictions - -import dagger.Binds -import dagger.Module -import fr.free.nrw.commons.depictions.Media.DepictedImagesContract -import fr.free.nrw.commons.depictions.Media.DepictedImagesPresenter -import fr.free.nrw.commons.depictions.subClass.SubDepictionListContract -import fr.free.nrw.commons.depictions.subClass.SubDepictionListPresenter - -/** - * The Dagger Module for explore:depictions related presenters and (some other objects maybe in future) - */ -@Module -abstract class DepictionModule { - @Binds - abstract fun SubDepictionListPresenter.bindsSubDepictionListPresenter() - : SubDepictionListContract.UserActionListener - - - @Binds - abstract fun DepictedImagesPresenter.bindsDepictedImagesContractPresenter() - : DepictedImagesContract.Presenter -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.kt b/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.kt deleted file mode 100644 index c5d886d80..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesContract.kt +++ /dev/null @@ -1,12 +0,0 @@ -package fr.free.nrw.commons.depictions.Media - -import fr.free.nrw.commons.Media -import fr.free.nrw.commons.explore.PagingContract - -/** - * Contract with which DepictedImagesFragment and its presenter will talk to each other - */ -interface DepictedImagesContract { - interface View : PagingContract.View - interface Presenter : PagingContract.Presenter -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/models/Continue.java b/app/src/main/java/fr/free/nrw/commons/depictions/models/Continue.java deleted file mode 100644 index 2365391a5..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/models/Continue.java +++ /dev/null @@ -1,57 +0,0 @@ -package fr.free.nrw.commons.depictions.models; -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -/** - * Model class for object obtained while parsing depiction response - */ -public class Continue { - - @SerializedName("sroffset") - @Expose - private Integer sroffset; - @SerializedName("continue") - @Expose - private String _continue; - - /** - * No args constructor for use in serialization - * - */ - public Continue() { - } - - /** - * - * @param sroffset - * @param _continue - */ - public Continue(Integer sroffset, String _continue) { - super(); - this.sroffset = sroffset; - this._continue = _continue; - } - - /** - * gets sroffset from Continue object - */ - public Integer getSroffset() { - return sroffset; - } - - public void setSroffset(Integer sroffset) { - this.sroffset = sroffset; - } - - /** - * gets continue string from Continue object - */ - public String getContinue() { - return _continue; - } - - public void setContinue(String _continue) { - this._continue = _continue; - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/models/Query.java b/app/src/main/java/fr/free/nrw/commons/depictions/models/Query.java deleted file mode 100644 index 358527fe7..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/models/Query.java +++ /dev/null @@ -1,60 +0,0 @@ -package fr.free.nrw.commons.depictions.models; -import java.util.List; -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -/** - * Model class for object obtained while parsing depiction response - * - * the getSearch() function is used to parse media - */ -public class Query { - - @SerializedName("searchinfo") - @Expose - private Searchinfo searchinfo; - @SerializedName("search") - @Expose - private List search = null; - - /** - * No args constructor for use in serialization - * - */ - public Query() { - } - - /** - * - * @param search - * @param searchinfo - */ - public Query(Searchinfo searchinfo, List search) { - super(); - this.searchinfo = searchinfo; - this.search = search; - } - - /** - * return searchInfo - */ - public Searchinfo getSearchinfo() { - return searchinfo; - } - - public void setSearchinfo(Searchinfo searchinfo) { - this.searchinfo = searchinfo; - } - - /** - * the getSearch() function is used to parse media - */ - public List getSearch() { - return search; - } - - public void setSearch(List search) { - this.search = search; - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/models/Search.java b/app/src/main/java/fr/free/nrw/commons/depictions/models/Search.java deleted file mode 100644 index fbff3616a..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/models/Search.java +++ /dev/null @@ -1,140 +0,0 @@ -package fr.free.nrw.commons.depictions.models; - -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -/** - * Model class for object obtained while parsing depiction response - * this class contains all the details of for the media object - */ - -public class Search { - - @SerializedName("ns") - @Expose - private Integer ns; - @SerializedName("title") - @Expose - private String title; - @SerializedName("pageid") - @Expose - private Integer pageid; - @SerializedName("size") - @Expose - private Integer size; - @SerializedName("wordcount") - @Expose - private Integer wordcount; - @SerializedName("snippet") - @Expose - private String snippet; - @SerializedName("timestamp") - @Expose - private String timestamp; - - /** - * No args constructor for use in serialization - * - */ - public Search() { - } - - /** - * - * @param timestamp - * @param title - * @param ns - * @param snippet - * @param wordcount - * @param size - * @param pageid - */ - public Search(Integer ns, String title, Integer pageid, Integer size, Integer wordcount, String snippet, String timestamp) { - super(); - this.ns = ns; - this.title = title; - this.pageid = pageid; - this.size = size; - this.wordcount = wordcount; - this.snippet = snippet; - this.timestamp = timestamp; - } - - /** - * returns ns int from Search object - */ - public Integer getNs() { - return ns; - } - - public void setNs(Integer ns) { - this.ns = ns; - } - - /** - * returns title string from Search object - */ - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - /** - * returns pageid int from Search object - */ - public Integer getPageid() { - return pageid; - } - - public void setPageid(Integer pageid) { - this.pageid = pageid; - } - - /** - * returns size int from Search object - */ - public Integer getSize() { - return size; - } - - public void setSize(Integer size) { - this.size = size; - } - - /** - * returns wordcount int from Search object - */ - public Integer getWordcount() { - return wordcount; - } - - public void setWordcount(Integer wordcount) { - this.wordcount = wordcount; - } - - /** - * returns snippet String from Search object - */ - public String getSnippet() { - return snippet; - } - - public void setSnippet(String snippet) { - this.snippet = snippet; - } - - /** - * returns ns int from Search object - */ - public String getTimestamp() { - return timestamp; - } - - public void setTimestamp(String timestamp) { - this.timestamp = timestamp; - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/models/Searchinfo.java b/app/src/main/java/fr/free/nrw/commons/depictions/models/Searchinfo.java deleted file mode 100644 index f04f62d0e..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/models/Searchinfo.java +++ /dev/null @@ -1,42 +0,0 @@ -package fr.free.nrw.commons.depictions.models; -import com.google.gson.annotations.Expose; -import com.google.gson.annotations.SerializedName; - -/** - * Model class for object obtained while parsing query object - */ - -public class Searchinfo { - - @SerializedName("totalhits") - @Expose - private Integer totalhits; - - /** - * No args constructor for use in serialization - * - */ - public Searchinfo() { - } - - /** - * - * @param totalhits - */ - public Searchinfo(Integer totalhits) { - super(); - this.totalhits = totalhits; - } - - /** - * returns "totalhint" integer in SearchInfo object - */ - public Integer getTotalhits() { - return totalhits; - } - - public void setTotalhits(Integer totalhits) { - this.totalhits = totalhits; - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionAdapter.kt b/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionAdapter.kt deleted file mode 100644 index f41a38f33..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionAdapter.kt +++ /dev/null @@ -1,11 +0,0 @@ -package fr.free.nrw.commons.depictions.subClass - -import fr.free.nrw.commons.explore.depictions.depictionDelegate -import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem - -class SubDepictionAdapter(clickListener: (DepictedItem) -> Unit) : - BaseDelegateAdapter( - depictionDelegate(clickListener), - areItemsTheSame = { oldItem, newItem -> oldItem.id == newItem.id } - ) diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListContract.java b/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListContract.java deleted file mode 100644 index 440989c1d..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListContract.java +++ /dev/null @@ -1,32 +0,0 @@ -package fr.free.nrw.commons.depictions.subClass; - -import fr.free.nrw.commons.BasePresenter; -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; -import java.io.IOException; -import java.util.List; - -/** - * The contract with which SubDepictionListFragment and its presenter would talk to each other - */ -public interface SubDepictionListContract { - - interface View { - - void onSuccess(List mediaList); - - void initErrorView(); - - void showSnackbar(); - - void setIsLastPage(boolean b); - - } - - interface UserActionListener extends BasePresenter { - - void initSubDepictionList(String qid, Boolean isParentClass) throws IOException; - - String getQuery(); - - } -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListFragment.java b/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListFragment.java deleted file mode 100644 index 6cd22fba5..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListFragment.java +++ /dev/null @@ -1,144 +0,0 @@ -package fr.free.nrw.commons.depictions.subClass; - -import static android.view.View.GONE; -import static android.view.View.VISIBLE; - -import android.content.res.Configuration; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ProgressBar; -import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import butterknife.BindView; -import butterknife.ButterKnife; -import dagger.android.support.DaggerFragment; -import fr.free.nrw.commons.R; -import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity; -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; -import fr.free.nrw.commons.utils.NetworkUtils; -import fr.free.nrw.commons.utils.ViewUtil; -import java.io.IOException; -import java.util.List; -import java.util.Locale; -import javax.inject.Inject; -import kotlin.Unit; - -/** - * Fragment for parent classes and child classes of Depicted items in Explore - */ -public class SubDepictionListFragment extends DaggerFragment implements SubDepictionListContract.View { - - @BindView(R.id.imagesListBox) - RecyclerView depictionsRecyclerView; - @BindView(R.id.imageSearchInProgress) - ProgressBar progressBar; - @BindView(R.id.imagesNotFound) - TextView depictionNotFound; - @BindView(R.id.bottomProgressBar) - ProgressBar bottomProgressBar; - /** - * Keeps a record of whether current instance of the fragment if of SubClass or ParentClass - */ - private boolean isParentClass = false; - private SubDepictionAdapter depictionsAdapter; - RecyclerView.LayoutManager layoutManager; - /** - * Stores entityId for the depiction - */ - private String entityId; - /** - * Stores name of the depiction searched - */ - private String depictsName; - - @Inject SubDepictionListPresenter presenter; - - private void initViews() { - if (getArguments() != null) { - depictsName = getArguments().getString("wikidataItemName"); - entityId = getArguments().getString("entityId"); - isParentClass = getArguments().getBoolean("isParentClass"); - if (entityId != null) { - initList(entityId, isParentClass); - } - } - } - - private void initList(String qid, Boolean isParentClass) { - if (!NetworkUtils.isInternetConnectionEstablished(getContext())) { - handleNoInternet(); - } else { - progressBar.setVisibility(View.VISIBLE); - try { - presenter.initSubDepictionList(qid, isParentClass); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - @Nullable - @Override - public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { - View v = inflater.inflate(R.layout.fragment_browse_image, container, false); - ButterKnife.bind(this, v); - presenter.onAttachView(this); - isParentClass = false; - depictionNotFound.setVisibility(GONE); - if (getActivity().getResources().getConfiguration().orientation - == Configuration.ORIENTATION_PORTRAIT) { - layoutManager = new LinearLayoutManager(getContext()); - } else { - layoutManager = new GridLayoutManager(getContext(), 2); - } - initViews(); - depictionsRecyclerView.setLayoutManager(layoutManager); - depictionsAdapter = new SubDepictionAdapter(depictedItem -> { - // Open SubDepiction Details page - getActivity().finish(); - WikidataItemDetailsActivity.startYourself(getContext(), depictedItem); - return Unit.INSTANCE; - }); - depictionsRecyclerView.setAdapter(depictionsAdapter); - return v; - } - - private void handleNoInternet() { - progressBar.setVisibility(GONE); - ViewUtil.showShortSnackbar(depictionsRecyclerView, R.string.no_internet); - } - - @Override - public void onSuccess(List mediaList) { - progressBar.setVisibility(View.GONE); - depictionNotFound.setVisibility(GONE); - bottomProgressBar.setVisibility(GONE); - depictionsAdapter.addAll(mediaList); - } - - @Override - public void initErrorView() { - progressBar.setVisibility(GONE); - bottomProgressBar.setVisibility(GONE); - depictionNotFound.setVisibility(VISIBLE); - String no_depiction = getString(isParentClass? R.string.no_parent_classes: R.string.no_child_classes); - depictionNotFound.setText(String.format(Locale.getDefault(), no_depiction, depictsName)); - - } - - @Override - public void showSnackbar() { - ViewUtil.showShortSnackbar(depictionsRecyclerView, R.string.error_loading_depictions); - } - - @Override - public void setIsLastPage(boolean b) { - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListPresenter.java b/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListPresenter.java deleted file mode 100644 index 61a1dc29b..000000000 --- a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/SubDepictionListPresenter.java +++ /dev/null @@ -1,116 +0,0 @@ -package fr.free.nrw.commons.depictions.subClass; - -import static fr.free.nrw.commons.di.CommonsApplicationModule.IO_THREAD; -import static fr.free.nrw.commons.di.CommonsApplicationModule.MAIN_THREAD; - -import fr.free.nrw.commons.explore.depictions.DepictsClient; -import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao; -import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient; -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem; -import io.reactivex.Scheduler; -import io.reactivex.disposables.CompositeDisposable; -import java.io.IOException; -import java.lang.reflect.Proxy; -import java.util.ArrayList; -import java.util.List; -import javax.inject.Inject; -import javax.inject.Named; -import timber.log.Timber; - -/** -* Presenter for parent classes and child classes of Depicted items in Explore - */ -public class SubDepictionListPresenter implements SubDepictionListContract.UserActionListener { - - /** - * This creates a dynamic proxy instance of the class, - * proxy is to control access to the target object - * here our target object is the view. - * Thus we when onDettach method of fragment is called we replace the binding of view to our object with the proxy instance - */ - private static final SubDepictionListContract.View DUMMY = (SubDepictionListContract.View) Proxy - .newProxyInstance( - SubDepictionListContract.View.class.getClassLoader(), - new Class[]{SubDepictionListContract.View.class}, - (proxy, method, methodArgs) -> null); - - private final Scheduler ioScheduler; - private final Scheduler mainThreadScheduler; - private SubDepictionListContract.View view = DUMMY; - RecentSearchesDao recentSearchesDao; - /** - * Value of the search query - */ - public String query; - protected CompositeDisposable compositeDisposable = new CompositeDisposable(); - DepictsClient depictsClient; - private List queryList = new ArrayList<>(); - OkHttpJsonApiClient okHttpJsonApiClient; - - @Inject - public SubDepictionListPresenter(RecentSearchesDao recentSearchesDao, DepictsClient depictsClient, OkHttpJsonApiClient okHttpJsonApiClient, @Named(IO_THREAD) Scheduler ioScheduler, - @Named(MAIN_THREAD) Scheduler mainThreadScheduler) { - this.recentSearchesDao = recentSearchesDao; - this.ioScheduler = ioScheduler; - this.mainThreadScheduler = mainThreadScheduler; - this.depictsClient = depictsClient; - this.okHttpJsonApiClient = okHttpJsonApiClient; - } - @Override - public void onAttachView(SubDepictionListContract.View view) { - this.view = view; - } - - @Override - public void onDetachView() { - this.view = DUMMY; - } - - @Override - public void initSubDepictionList(String qid, Boolean isParentClass) throws IOException { - if (isParentClass) { - compositeDisposable.add(okHttpJsonApiClient.getParentQIDs(qid) - .subscribeOn(ioScheduler) - .observeOn(mainThreadScheduler) - .subscribe(this::handleSuccess, this::handleError)); - } else { - compositeDisposable.add(okHttpJsonApiClient.getChildQIDs(qid) - .subscribeOn(ioScheduler) - .observeOn(mainThreadScheduler) - .subscribe(this::handleSuccess, this::handleError)); - } - - } - - @Override - public String getQuery() { - return query; - } - - /** - * Handles the success scenario - * it initializes the recycler view by adding items to the adapter - */ - public void handleSuccess(List mediaList) { - if (mediaList == null || mediaList.isEmpty()) { - if(queryList.isEmpty()){ - view.initErrorView(); - }else{ - view.setIsLastPage(true); - } - } else { - this.queryList.addAll(mediaList); - view.onSuccess(mediaList); - } - } - - /** - * Logs and handles API error scenario - */ - private void handleError(Throwable throwable) { - Timber.e(throwable, "Error occurred while loading queried depictions"); - view.initErrorView(); - view.showSnackbar(); - } - -} diff --git a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java index db7c7fd26..a1683d79b 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java @@ -11,9 +11,9 @@ import fr.free.nrw.commons.bookmarks.BookmarksActivity; import fr.free.nrw.commons.category.CategoryDetailsActivity; import fr.free.nrw.commons.category.CategoryImagesActivity; import fr.free.nrw.commons.contributions.MainActivity; -import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity; +import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity; import fr.free.nrw.commons.explore.SearchActivity; -import fr.free.nrw.commons.explore.categories.ExploreActivity; +import fr.free.nrw.commons.explore.ExploreActivity; import fr.free.nrw.commons.notification.NotificationActivity; import fr.free.nrw.commons.review.ReviewActivity; import fr.free.nrw.commons.settings.SettingsActivity; diff --git a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java index 5c97ce9d9..4153f5c86 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java +++ b/app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java @@ -11,7 +11,7 @@ import dagger.android.support.AndroidSupportInjectionModule; import fr.free.nrw.commons.CommonsApplication; import fr.free.nrw.commons.auth.LoginActivity; import fr.free.nrw.commons.contributions.ContributionsModule; -import fr.free.nrw.commons.depictions.DepictionModule; +import fr.free.nrw.commons.explore.depictions.DepictionModule; import fr.free.nrw.commons.explore.SearchModule; import fr.free.nrw.commons.review.ReviewController; import fr.free.nrw.commons.settings.SettingsFragment; diff --git a/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java b/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java index b60b68bf2..89620306f 100644 --- a/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java +++ b/app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java @@ -8,10 +8,11 @@ import fr.free.nrw.commons.category.CategoryImagesListFragment; import fr.free.nrw.commons.category.SubCategoryListFragment; import fr.free.nrw.commons.contributions.ContributionsFragment; import fr.free.nrw.commons.contributions.ContributionsListFragment; -import fr.free.nrw.commons.depictions.Media.DepictedImagesFragment; -import fr.free.nrw.commons.depictions.subClass.SubDepictionListFragment; +import fr.free.nrw.commons.explore.depictions.child.ChildDepictionsFragment; +import fr.free.nrw.commons.explore.depictions.media.DepictedImagesFragment; +import fr.free.nrw.commons.explore.depictions.parent.ParentDepictionsFragment; import fr.free.nrw.commons.explore.categories.SearchCategoryFragment; -import fr.free.nrw.commons.explore.depictions.SearchDepictionsFragment; +import fr.free.nrw.commons.explore.depictions.search.SearchDepictionsFragment; import fr.free.nrw.commons.explore.media.SearchMediaFragment; import fr.free.nrw.commons.explore.recentsearches.RecentSearchesFragment; import fr.free.nrw.commons.media.MediaDetailFragment; @@ -51,9 +52,6 @@ public abstract class FragmentBuilderModule { @ContributesAndroidInjector abstract DepictedImagesFragment bindDepictedImagesFragment(); - @ContributesAndroidInjector - abstract SubDepictionListFragment bindSubDepictionListFragment(); - @ContributesAndroidInjector abstract SubCategoryListFragment bindSubCategoryListFragment(); @@ -95,4 +93,10 @@ public abstract class FragmentBuilderModule { @ContributesAndroidInjector abstract MediaLicenseFragment bindMediaLicenseFragment(); + + @ContributesAndroidInjector + abstract ParentDepictionsFragment bindParentDepictionsFragment(); + + @ContributesAndroidInjector + abstract ChildDepictionsFragment bindChildDepictionsFragment(); } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/ExploreActivity.java b/app/src/main/java/fr/free/nrw/commons/explore/ExploreActivity.java similarity index 98% rename from app/src/main/java/fr/free/nrw/commons/explore/categories/ExploreActivity.java rename to app/src/main/java/fr/free/nrw/commons/explore/ExploreActivity.java index de4884b7f..dcdb6a5cb 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/categories/ExploreActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/ExploreActivity.java @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.explore.categories; +package fr.free.nrw.commons.explore; import android.content.Context; import android.content.Intent; @@ -19,8 +19,6 @@ import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.category.CategoryImagesCallback; import fr.free.nrw.commons.category.CategoryImagesListFragment; -import fr.free.nrw.commons.explore.SearchActivity; -import fr.free.nrw.commons.explore.ViewPagerAdapter; import fr.free.nrw.commons.media.MediaDetailPagerFragment; import fr.free.nrw.commons.theme.NavigationBaseActivity; import java.util.ArrayList; diff --git a/app/src/main/java/fr/free/nrw/commons/explore/FooterAdapter.kt b/app/src/main/java/fr/free/nrw/commons/explore/FooterAdapter.kt deleted file mode 100644 index f51dad4e6..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/FooterAdapter.kt +++ /dev/null @@ -1,54 +0,0 @@ -package fr.free.nrw.commons.explore - -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/SearchActivity.java b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java index ebb0b1ad7..e7c016bfe 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/SearchActivity.java @@ -20,7 +20,7 @@ import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.category.CategoryImagesCallback; import fr.free.nrw.commons.explore.categories.SearchCategoryFragment; -import fr.free.nrw.commons.explore.depictions.SearchDepictionsFragment; +import fr.free.nrw.commons.explore.depictions.search.SearchDepictionsFragment; import fr.free.nrw.commons.explore.media.SearchMediaFragment; import fr.free.nrw.commons.explore.recentsearches.RecentSearch; import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao; diff --git a/app/src/main/java/fr/free/nrw/commons/explore/SearchCategoriesFragmentPresenter.kt b/app/src/main/java/fr/free/nrw/commons/explore/SearchCategoriesFragmentPresenter.kt deleted file mode 100644 index 18105baff..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/SearchCategoriesFragmentPresenter.kt +++ /dev/null @@ -1,14 +0,0 @@ -package fr.free.nrw.commons.explore - -import fr.free.nrw.commons.di.CommonsApplicationModule -import fr.free.nrw.commons.explore.categories.SearchCategoriesFragmentContract -import fr.free.nrw.commons.explore.categories.PageableCategoriesDataSource -import io.reactivex.Scheduler -import javax.inject.Inject -import javax.inject.Named - -class SearchCategoriesFragmentPresenter @Inject constructor( - @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, - dataSourceFactory: PageableCategoriesDataSource -) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), - SearchCategoriesFragmentContract.Presenter diff --git a/app/src/main/java/fr/free/nrw/commons/explore/SearchModule.kt b/app/src/main/java/fr/free/nrw/commons/explore/SearchModule.kt index 628394438..40a3c32ef 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/SearchModule.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/SearchModule.kt @@ -2,11 +2,12 @@ package fr.free.nrw.commons.explore import dagger.Binds import dagger.Module -import fr.free.nrw.commons.explore.categories.SearchCategoriesFragmentContract -import fr.free.nrw.commons.explore.depictions.SearchDepictionsFragmentContract -import fr.free.nrw.commons.explore.depictions.SearchDepictionsFragmentPresenter -import fr.free.nrw.commons.explore.media.SearchMediaFragmentContract +import fr.free.nrw.commons.explore.categories.SearchCategoriesFragmentPresenter +import fr.free.nrw.commons.explore.categories.SearchCategoriesFragmentPresenterImpl +import fr.free.nrw.commons.explore.depictions.search.SearchDepictionsFragmentPresenter +import fr.free.nrw.commons.explore.depictions.search.SearchDepictionsFragmentPresenterImpl import fr.free.nrw.commons.explore.media.SearchMediaFragmentPresenter +import fr.free.nrw.commons.explore.media.SearchMediaFragmentPresenterImpl /** * The Dagger Module for explore:depictions related presenters and (some other objects maybe in future) @@ -14,14 +15,14 @@ import fr.free.nrw.commons.explore.media.SearchMediaFragmentPresenter @Module abstract class SearchModule { @Binds - abstract fun SearchDepictionsFragmentPresenter.bindsSearchDepictionsFragmentPresenter() - : SearchDepictionsFragmentContract.Presenter + abstract fun SearchDepictionsFragmentPresenterImpl.bindsSearchDepictionsFragmentPresenter() + : SearchDepictionsFragmentPresenter @Binds - abstract fun SearchCategoriesFragmentPresenter.bindsSearchCategoriesFragmentPresenter() - : SearchCategoriesFragmentContract.Presenter + abstract fun SearchCategoriesFragmentPresenterImpl.bindsSearchCategoriesFragmentPresenter() + : SearchCategoriesFragmentPresenter @Binds - abstract fun SearchMediaFragmentPresenter.bindsSearchMediaFragmentPresenter() - : SearchMediaFragmentContract.Presenter + abstract fun SearchMediaFragmentPresenterImpl.bindsSearchMediaFragmentPresenter() + : SearchMediaFragmentPresenter } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/PageableCategoriesDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/categories/PageableCategoriesDataSource.kt index 4599b132a..aa558b388 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/categories/PageableCategoriesDataSource.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/categories/PageableCategoriesDataSource.kt @@ -1,8 +1,8 @@ package fr.free.nrw.commons.explore.categories import fr.free.nrw.commons.category.CategoryClient -import fr.free.nrw.commons.explore.LiveDataConverter -import fr.free.nrw.commons.explore.PageableBaseDataSource +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource import javax.inject.Inject class PageableCategoriesDataSource @Inject constructor( diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/PagedSearchCategoriesAdapter.kt b/app/src/main/java/fr/free/nrw/commons/explore/categories/PagedSearchCategoriesAdapter.kt index 52eb49165..fd41a6b73 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/categories/PagedSearchCategoriesAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/categories/PagedSearchCategoriesAdapter.kt @@ -6,8 +6,8 @@ import androidx.paging.PagedListAdapter import androidx.recyclerview.widget.DiffUtil import fr.free.nrw.commons.R import fr.free.nrw.commons.category.CATEGORY_PREFIX -import fr.free.nrw.commons.explore.BaseViewHolder -import fr.free.nrw.commons.explore.inflate +import fr.free.nrw.commons.explore.paging.BaseViewHolder +import fr.free.nrw.commons.explore.paging.inflate import kotlinx.android.synthetic.main.item_recent_searches.* diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentContract.kt b/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentContract.kt deleted file mode 100644 index 786556b0a..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentContract.kt +++ /dev/null @@ -1,8 +0,0 @@ -package fr.free.nrw.commons.explore.categories - -import fr.free.nrw.commons.explore.PagingContract - -interface SearchCategoriesFragmentContract { - interface View : PagingContract.View - interface Presenter : PagingContract.Presenter -} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentPresenterImpl.kt b/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentPresenterImpl.kt new file mode 100644 index 000000000..de6234791 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoriesFragmentPresenterImpl.kt @@ -0,0 +1,16 @@ +package fr.free.nrw.commons.explore.categories + +import fr.free.nrw.commons.di.CommonsApplicationModule +import fr.free.nrw.commons.explore.paging.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.PagingContract +import io.reactivex.Scheduler +import javax.inject.Inject +import javax.inject.Named + +interface SearchCategoriesFragmentPresenter : PagingContract.Presenter + +class SearchCategoriesFragmentPresenterImpl @Inject constructor( + @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, + dataSourceFactory: PageableCategoriesDataSource +) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), + SearchCategoriesFragmentPresenter diff --git a/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoryFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoryFragment.kt index 0055d11dd..3393aace5 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoryFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/categories/SearchCategoryFragment.kt @@ -2,8 +2,8 @@ package fr.free.nrw.commons.explore.categories import fr.free.nrw.commons.R import fr.free.nrw.commons.category.CategoryDetailsActivity -import fr.free.nrw.commons.explore.BasePagingFragment -import fr.free.nrw.commons.explore.PagingContract +import fr.free.nrw.commons.explore.paging.BasePagingFragment + import javax.inject.Inject /** @@ -11,7 +11,7 @@ import javax.inject.Inject */ class SearchCategoryFragment : BasePagingFragment() { @Inject - lateinit var presenter: SearchCategoriesFragmentContract.Presenter + lateinit var presenter: SearchCategoriesFragmentPresenter override val errorTextId: Int = R.string.error_loading_categories 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 f50e41764..6f6805692 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 @@ -6,7 +6,7 @@ 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.inflate +import fr.free.nrw.commons.explore.paging.inflate import fr.free.nrw.commons.upload.structure.depictions.DepictedItem import kotlinx.android.extensions.LayoutContainer import kotlinx.android.synthetic.main.item_depictions.* diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapterDelegates.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapterDelegates.kt deleted file mode 100644 index e1c37c0e5..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionAdapterDelegates.kt +++ /dev/null @@ -1,21 +0,0 @@ -package fr.free.nrw.commons.explore.depictions - -import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateLayoutContainer -import fr.free.nrw.commons.R -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import kotlinx.android.synthetic.main.item_depictions.* - - -fun depictionDelegate(onDepictionClicked: (DepictedItem) -> Unit) = - adapterDelegateLayoutContainer(R.layout.item_depictions) { - containerView.setOnClickListener { onDepictionClicked(item) } - bind { - depicts_label.text = item.name - description.text = item.description - if (item.imageUrl?.isNotBlank() == true) { - depicts_image.setImageURI(item.imageUrl) - } else { - depicts_image.setActualImageResource(R.drawable.ic_wikidata_logo_24dp) - } - } - } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionModule.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionModule.kt new file mode 100644 index 000000000..cb8ee6999 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/DepictionModule.kt @@ -0,0 +1,29 @@ +package fr.free.nrw.commons.explore.depictions + +import dagger.Binds +import dagger.Module +import fr.free.nrw.commons.explore.depictions.child.ChildDepictionsPresenter +import fr.free.nrw.commons.explore.depictions.child.ChildDepictionsPresenterImpl +import fr.free.nrw.commons.explore.depictions.media.DepictedImagesPresenter +import fr.free.nrw.commons.explore.depictions.media.DepictedImagesPresenterImpl +import fr.free.nrw.commons.explore.depictions.parent.ParentDepictionsPresenter +import fr.free.nrw.commons.explore.depictions.parent.ParentDepictionsPresenterImpl + +/** + * The Dagger Module for explore:depictions related presenters and (some other objects maybe in future) + */ +@Module +abstract class DepictionModule { + + @Binds + abstract fun ParentDepictionsPresenterImpl.bindsParentDepictionPresenter() + : ParentDepictionsPresenter + + @Binds + abstract fun ChildDepictionsPresenterImpl.bindsChildDepictionPresenter() + : ChildDepictionsPresenter + + @Binds + abstract fun DepictedImagesPresenterImpl.bindsDepictedImagesContractPresenter() + : DepictedImagesPresenter +} 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 b9a4d15a0..14e674744 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 @@ -1,31 +1,21 @@ package fr.free.nrw.commons.explore.depictions -import fr.free.nrw.commons.depictions.subClass.models.SparqlResponse -import fr.free.nrw.commons.media.MediaInterface +import fr.free.nrw.commons.mwapi.SparqlResponse import fr.free.nrw.commons.upload.depicts.DepictsInterface import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import fr.free.nrw.commons.utils.CommonsDateUtil import io.reactivex.Observable import io.reactivex.Single import org.wikipedia.wikidata.Entities -import java.math.BigInteger -import java.security.MessageDigest -import java.security.NoSuchAlgorithmException -import java.text.ParseException import java.util.* import javax.inject.Inject import javax.inject.Singleton -const val LARGE_IMAGE_SIZE = "640px" -const val THUMB_IMAGE_SIZE = "70px" - /** * Depicts Client to handle custom calls to Commons Wikibase APIs */ @Singleton class DepictsClient @Inject constructor( - private val depictsInterface: DepictsInterface, - private val mediaInterface: MediaInterface + private val depictsInterface: DepictsInterface ) { /** @@ -40,10 +30,6 @@ class DepictsClient @Inject constructor( .map { it.entities().values.map(::DepictedItem) } } - private fun getUrl(title: String): String { - return getImageUrl(title, LARGE_IMAGE_SIZE) - } - fun getEntities(ids: String): Single { return depictsInterface.getEntities(ids) } @@ -57,63 +43,4 @@ class DepictsClient @Inject constructor( .flatMap { getEntities(it).toObservable() } .map { it.entities().values.map(::DepictedItem) } } - - companion object { - - /** - * Get url for the image from media of depictions - * Ex: Tiger_Woods - * Value: https://upload.wikimedia.org/wikipedia/commons/thumb/6/67/Tiger_Woods.jpg/70px-Tiger_Woods.jpg - */ - fun getImageUrl(title: String, size: String): String { - return title.substringAfter(":") - .replace(" ", "_") - .let { - val MD5Hash = getMd5(it) - "https://upload.wikimedia.org/wikipedia/commons/thumb/${MD5Hash[0]}/${MD5Hash[0]}${MD5Hash[1]}/$it/$size-$it" - } - } - - /** - * Generates MD5 hash for the filename - */ - fun getMd5(input: String): String { - return try { - - // Static getInstance method is called with hashing MD5 - val md = MessageDigest.getInstance("MD5") - - // digest() method is called to calculate message digest - // of an input digest() return array of byte - val messageDigest = md.digest(input.toByteArray()) - - // Convert byte array into signum representation - val no = BigInteger(1, messageDigest) - - // Convert message digest into hex value - var hashtext = no.toString(16) - while (hashtext.length < 32) { - hashtext = "0$hashtext" - } - hashtext - } // For specifying wrong message digest algorithms - catch (e: NoSuchAlgorithmException) { - throw RuntimeException(e) - } - } - - /** - * Parse the date string into the required format - * @param dateStr - * @return date in the required format - */ - private fun safeParseDate(dateStr: String): Date? { - return try { - CommonsDateUtil.getIso8601DateFormatShort().parse(dateStr) - } catch (e: ParseException) { - null - } - } - } - } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsFragment.kt new file mode 100644 index 000000000..4c288d08a --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsFragment.kt @@ -0,0 +1,13 @@ +package fr.free.nrw.commons.explore.depictions + +import fr.free.nrw.commons.R +import fr.free.nrw.commons.explore.paging.BasePagingFragment +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem + + +abstract class PageableDepictionsFragment : BasePagingFragment() { + override val errorTextId: Int = R.string.error_loading_depictions + override val pagedListAdapter by lazy { + DepictionAdapter { WikidataItemDetailsActivity.startYourself(context, it) } + } +} 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 deleted file mode 100644 index 413ee017e..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSource.kt +++ /dev/null @@ -1,63 +0,0 @@ -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/SearchDepictionsFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragment.kt deleted file mode 100644 index 51f7448da..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragment.kt +++ /dev/null @@ -1,27 +0,0 @@ -package fr.free.nrw.commons.explore.depictions - -import fr.free.nrw.commons.R -import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity -import fr.free.nrw.commons.explore.BasePagingFragment -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import javax.inject.Inject - -/** - * Display depictions in search fragment - */ -class SearchDepictionsFragment : BasePagingFragment(), - SearchDepictionsFragmentContract.View { - @Inject - lateinit var presenter: SearchDepictionsFragmentContract.Presenter - - override val errorTextId: Int = R.string.error_loading_depictions - - override val injectedPresenter - get() = presenter - - override val pagedListAdapter by lazy { - DepictionAdapter { WikidataItemDetailsActivity.startYourself(context, it) } - } - - override fun getEmptyText(query: String) = getString(R.string.depictions_not_found, query) -} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentContract.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentContract.kt deleted file mode 100644 index 54e0f9288..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentContract.kt +++ /dev/null @@ -1,12 +0,0 @@ -package fr.free.nrw.commons.explore.depictions - -import fr.free.nrw.commons.explore.PagingContract -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem - -/** - * The contract with with SearchDepictionsFragment and its presenter would talk to each other - */ -interface SearchDepictionsFragmentContract { - interface View : PagingContract.View - interface Presenter : PagingContract.Presenter -} 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 deleted file mode 100644 index 90bdcdc40..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactory.kt +++ /dev/null @@ -1,88 +0,0 @@ -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/depictions/WikidataItemDetailsActivity.java b/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java similarity index 87% rename from app/src/main/java/fr/free/nrw/commons/depictions/WikidataItemDetailsActivity.java rename to app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java index 7aca8d272..176463706 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/WikidataItemDetailsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/WikidataItemDetailsActivity.java @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.depictions; +package fr.free.nrw.commons.explore.depictions; import android.content.Context; import android.content.Intent; @@ -13,8 +13,9 @@ import butterknife.ButterKnife; import com.google.android.material.tabs.TabLayout; import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; -import fr.free.nrw.commons.depictions.Media.DepictedImagesFragment; -import fr.free.nrw.commons.depictions.subClass.SubDepictionListFragment; +import fr.free.nrw.commons.explore.depictions.child.ChildDepictionsFragment; +import fr.free.nrw.commons.explore.depictions.media.DepictedImagesFragment; +import fr.free.nrw.commons.explore.depictions.parent.ParentDepictionsFragment; import fr.free.nrw.commons.explore.ViewPagerAdapter; import fr.free.nrw.commons.media.MediaDetailPagerFragment; import fr.free.nrw.commons.theme.NavigationBaseActivity; @@ -87,28 +88,23 @@ public class WikidataItemDetailsActivity extends NavigationBaseActivity implemen List fragmentList = new ArrayList<>(); List titleList = new ArrayList<>(); depictionImagesListFragment = new DepictedImagesFragment(); - SubDepictionListFragment subDepictionListFragment = new SubDepictionListFragment(); - SubDepictionListFragment parentDepictionListFragment = new SubDepictionListFragment(); + ChildDepictionsFragment childDepictionsFragment = new ChildDepictionsFragment(); + ParentDepictionsFragment parentDepictionsFragment = new ParentDepictionsFragment(); wikidataItemName = getIntent().getStringExtra("wikidataItemName"); String entityId = getIntent().getStringExtra("entityId"); if (getIntent() != null && wikidataItemName != null) { Bundle arguments = new Bundle(); arguments.putString("wikidataItemName", wikidataItemName); arguments.putString("entityId", entityId); - arguments.putBoolean("isParentClass", false); depictionImagesListFragment.setArguments(arguments); - subDepictionListFragment.setArguments(arguments); - Bundle parentClassArguments = new Bundle(); - parentClassArguments.putString("wikidataItemName", wikidataItemName); - parentClassArguments.putString("entityId", entityId); - parentClassArguments.putBoolean("isParentClass", true); - parentDepictionListFragment.setArguments(parentClassArguments); + parentDepictionsFragment.setArguments(arguments); + childDepictionsFragment.setArguments(arguments); } fragmentList.add(depictionImagesListFragment); titleList.add(getResources().getString(R.string.title_for_media)); - fragmentList.add(subDepictionListFragment); + fragmentList.add(childDepictionsFragment); titleList.add(getResources().getString(R.string.title_for_child_classes)); - fragmentList.add(parentDepictionListFragment); + fragmentList.add(parentDepictionsFragment); titleList.add(getResources().getString(R.string.title_for_parent_classes)); viewPagerAdapter.setTabData(fragmentList, titleList); viewPager.setOffscreenPageLimit(2); @@ -183,7 +179,6 @@ public class WikidataItemDetailsActivity extends NavigationBaseActivity implemen */ public static void startYourself(Context context, DepictedItem depictedItem) { Intent intent = new Intent(context, WikidataItemDetailsActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra("wikidataItemName", depictedItem.getName()); intent.putExtra("entityId", depictedItem.getId()); context.startActivity(intent); diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsFragment.kt new file mode 100644 index 000000000..ae5cc755e --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsFragment.kt @@ -0,0 +1,24 @@ +package fr.free.nrw.commons.explore.depictions.child + +import android.os.Bundle +import android.view.View +import fr.free.nrw.commons.R +import fr.free.nrw.commons.explore.depictions.PageableDepictionsFragment +import javax.inject.Inject + + +class ChildDepictionsFragment: PageableDepictionsFragment() { + @Inject + lateinit var presenter: ChildDepictionsPresenter + + override val injectedPresenter + get() = presenter + + override fun getEmptyText(query: String) = + getString(R.string.no_child_classes, arguments!!.getString("wikidataItemName")!!) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + onQueryUpdated(arguments!!.getString("entityId")!!) + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsPresenterImpl.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsPresenterImpl.kt new file mode 100644 index 000000000..b8c1abe63 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/ChildDepictionsPresenterImpl.kt @@ -0,0 +1,17 @@ +package fr.free.nrw.commons.explore.depictions.child + +import fr.free.nrw.commons.di.CommonsApplicationModule +import fr.free.nrw.commons.explore.paging.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.PagingContract +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import io.reactivex.Scheduler +import javax.inject.Inject +import javax.inject.Named + +interface ChildDepictionsPresenter : PagingContract.Presenter + +class ChildDepictionsPresenterImpl @Inject constructor( + @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, + dataSourceFactory: PageableChildDepictionsDataSource +) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), + ChildDepictionsPresenter diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSource.kt new file mode 100644 index 000000000..2fb549f28 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSource.kt @@ -0,0 +1,17 @@ +package fr.free.nrw.commons.explore.depictions.child + +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource +import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import javax.inject.Inject + +class PageableChildDepictionsDataSource @Inject constructor( + liveDataConverter: LiveDataConverter, + private val okHttpJsonApiClient: OkHttpJsonApiClient +) : PageableBaseDataSource(liveDataConverter) { + override val loadFunction = { limit: Int, startPosition: Int -> + okHttpJsonApiClient.getChildDepictions(query, startPosition, limit).blockingFirst() + } +} + diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/media/DepictedImagesFragment.kt similarity index 72% rename from app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.kt rename to app/src/main/java/fr/free/nrw/commons/explore/depictions/media/DepictedImagesFragment.kt index e33a621ef..92936a72d 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/media/DepictedImagesFragment.kt @@ -1,14 +1,14 @@ -package fr.free.nrw.commons.depictions.Media +package fr.free.nrw.commons.explore.depictions.media import android.os.Bundle import android.view.View -import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity +import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity import fr.free.nrw.commons.explore.media.PageableMediaFragment import javax.inject.Inject -class DepictedImagesFragment : PageableMediaFragment(), DepictedImagesContract.View { +class DepictedImagesFragment : PageableMediaFragment() { @Inject - lateinit var presenter: DepictedImagesContract.Presenter + lateinit var presenter: DepictedImagesPresenter override val injectedPresenter get() = presenter diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/media/DepictedImagesPresenterImpl.kt similarity index 56% rename from app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.kt rename to app/src/main/java/fr/free/nrw/commons/explore/depictions/media/DepictedImagesPresenterImpl.kt index 28004c67e..743b78e43 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/DepictedImagesPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/media/DepictedImagesPresenterImpl.kt @@ -1,17 +1,20 @@ -package fr.free.nrw.commons.depictions.Media +package fr.free.nrw.commons.explore.depictions.media import fr.free.nrw.commons.Media import fr.free.nrw.commons.di.CommonsApplicationModule -import fr.free.nrw.commons.explore.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.PagingContract import io.reactivex.Scheduler import javax.inject.Inject import javax.inject.Named +interface DepictedImagesPresenter : PagingContract.Presenter + /** * Presenter for DepictedImagesFragment */ -class DepictedImagesPresenter @Inject constructor( +class DepictedImagesPresenterImpl @Inject constructor( @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, dataSourceFactory: PageableDepictedMediaDataSource ) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), - DepictedImagesContract.Presenter + DepictedImagesPresenter diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/Media/PageableDepictedMediaDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/media/PageableDepictedMediaDataSource.kt similarity index 67% rename from app/src/main/java/fr/free/nrw/commons/depictions/Media/PageableDepictedMediaDataSource.kt rename to app/src/main/java/fr/free/nrw/commons/explore/depictions/media/PageableDepictedMediaDataSource.kt index 708bc77b1..912d47aba 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/Media/PageableDepictedMediaDataSource.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/media/PageableDepictedMediaDataSource.kt @@ -1,9 +1,9 @@ -package fr.free.nrw.commons.depictions.Media +package fr.free.nrw.commons.explore.depictions.media import fr.free.nrw.commons.Media -import fr.free.nrw.commons.explore.LiveDataConverter -import fr.free.nrw.commons.explore.PageableBaseDataSource -import fr.free.nrw.commons.explore.depictions.LoadFunction +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource +import fr.free.nrw.commons.explore.depictions.search.LoadFunction import fr.free.nrw.commons.media.MediaClient import javax.inject.Inject diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSource.kt new file mode 100644 index 000000000..e2459bf66 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSource.kt @@ -0,0 +1,17 @@ +package fr.free.nrw.commons.explore.depictions.parent + +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource +import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import javax.inject.Inject + +class PageableParentDepictionsDataSource @Inject constructor( + liveDataConverter: LiveDataConverter, + private val okHttpJsonApiClient: OkHttpJsonApiClient +) : PageableBaseDataSource(liveDataConverter) { + override val loadFunction = { limit: Int, startPosition: Int -> + okHttpJsonApiClient.getParentDepictions(query, startPosition, limit).blockingFirst() + } +} + diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsFragment.kt new file mode 100644 index 000000000..779764409 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsFragment.kt @@ -0,0 +1,24 @@ +package fr.free.nrw.commons.explore.depictions.parent + +import android.os.Bundle +import android.view.View +import fr.free.nrw.commons.R +import fr.free.nrw.commons.explore.depictions.PageableDepictionsFragment +import javax.inject.Inject + + +class ParentDepictionsFragment : PageableDepictionsFragment() { + @Inject + lateinit var presenter: ParentDepictionsPresenter + + override val injectedPresenter + get() = presenter + + override fun getEmptyText(query: String) = + getString(R.string.no_parent_classes, arguments!!.getString("wikidataItemName")!!) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + onQueryUpdated(arguments!!.getString("entityId")!!) + } +} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsPresenterImpl.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsPresenterImpl.kt new file mode 100644 index 000000000..db9ee9192 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/parent/ParentDepictionsPresenterImpl.kt @@ -0,0 +1,19 @@ +package fr.free.nrw.commons.explore.depictions.parent + +import fr.free.nrw.commons.di.CommonsApplicationModule +import fr.free.nrw.commons.explore.paging.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.PagingContract +import fr.free.nrw.commons.upload.structure.depictions.DepictedItem +import io.reactivex.Scheduler +import javax.inject.Inject +import javax.inject.Named + +interface ParentDepictionsPresenter : PagingContract.Presenter + +class ParentDepictionsPresenterImpl @Inject constructor( + @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, + dataSourceFactory: PageableParentDepictionsDataSource +) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), + ParentDepictionsPresenter { + +} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/PageableDepictionsDataSource.kt similarity index 67% rename from app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSource.kt rename to app/src/main/java/fr/free/nrw/commons/explore/depictions/search/PageableDepictionsDataSource.kt index aa60d9318..961d1afb2 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSource.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/PageableDepictionsDataSource.kt @@ -1,8 +1,9 @@ -package fr.free.nrw.commons.explore.depictions +package fr.free.nrw.commons.explore.depictions.search -import fr.free.nrw.commons.explore.LiveDataConverter -import fr.free.nrw.commons.explore.LoadingState -import fr.free.nrw.commons.explore.PageableBaseDataSource +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.LoadingState +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource +import fr.free.nrw.commons.explore.depictions.DepictsClient import fr.free.nrw.commons.upload.structure.depictions.DepictedItem import io.reactivex.processors.PublishProcessor import javax.inject.Inject diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragment.kt new file mode 100644 index 000000000..df70d7e58 --- /dev/null +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragment.kt @@ -0,0 +1,18 @@ +package fr.free.nrw.commons.explore.depictions.search + +import fr.free.nrw.commons.R +import fr.free.nrw.commons.explore.depictions.PageableDepictionsFragment +import javax.inject.Inject + +/** + * Display depictions in search fragment + */ +class SearchDepictionsFragment : PageableDepictionsFragment() { + @Inject + lateinit var presenter: SearchDepictionsFragmentPresenter + + override val injectedPresenter + get() = presenter + + override fun getEmptyText(query: String) = getString(R.string.depictions_not_found, query) +} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentPresenter.kt b/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragmentPresenterImpl.kt similarity index 57% rename from app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentPresenter.kt rename to app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragmentPresenterImpl.kt index ccc443918..e85b08e22 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/SearchDepictionsFragmentPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/depictions/search/SearchDepictionsFragmentPresenterImpl.kt @@ -1,17 +1,19 @@ -package fr.free.nrw.commons.explore.depictions +package fr.free.nrw.commons.explore.depictions.search import fr.free.nrw.commons.di.CommonsApplicationModule -import fr.free.nrw.commons.explore.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.PagingContract import fr.free.nrw.commons.upload.structure.depictions.DepictedItem import io.reactivex.Scheduler import javax.inject.Inject import javax.inject.Named +interface SearchDepictionsFragmentPresenter : PagingContract.Presenter /** * The presenter class for SearchDepictionsFragment */ -class SearchDepictionsFragmentPresenter @Inject constructor( +class SearchDepictionsFragmentPresenterImpl @Inject constructor( @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, dataSourceFactory: PageableDepictionsDataSource ) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), - SearchDepictionsFragmentContract.Presenter + SearchDepictionsFragmentPresenter diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaDataSource.kt index d5b4645e2..89bdf3879 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaDataSource.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaDataSource.kt @@ -1,9 +1,9 @@ package fr.free.nrw.commons.explore.media import fr.free.nrw.commons.Media -import fr.free.nrw.commons.explore.LiveDataConverter -import fr.free.nrw.commons.explore.PageableBaseDataSource -import fr.free.nrw.commons.explore.depictions.LoadFunction +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource +import fr.free.nrw.commons.explore.depictions.search.LoadFunction import fr.free.nrw.commons.media.MediaClient import javax.inject.Inject diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt index 1c911899d..5b6df8780 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/PageableMediaFragment.kt @@ -4,7 +4,7 @@ import android.os.Bundle import android.view.View import fr.free.nrw.commons.Media import fr.free.nrw.commons.R -import fr.free.nrw.commons.explore.BasePagingFragment +import fr.free.nrw.commons.explore.paging.BasePagingFragment import kotlinx.android.synthetic.main.fragment_search_paginated.* diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/PagedMediaAdapter.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/PagedMediaAdapter.kt index 3b8096553..43825158c 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/PagedMediaAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/PagedMediaAdapter.kt @@ -6,8 +6,8 @@ import androidx.paging.PagedListAdapter import androidx.recyclerview.widget.DiffUtil import fr.free.nrw.commons.Media 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.explore.paging.BaseViewHolder +import fr.free.nrw.commons.explore.paging.inflate import kotlinx.android.synthetic.main.layout_category_images.* class PagedMediaAdapter(private val onImageClicked: (Int) -> Unit) : diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragment.kt index feb7e3db2..d82fe7c83 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragment.kt @@ -7,15 +7,15 @@ import javax.inject.Inject /** * Displays the image search screen. */ -class SearchMediaFragment : PageableMediaFragment(), SearchMediaFragmentContract.View { +class SearchMediaFragment : PageableMediaFragment(){ @Inject - lateinit var presenter: SearchMediaFragmentContract.Presenter + lateinit var presenter: SearchMediaFragmentPresenter override val injectedPresenter get() = presenter override fun onItemClicked(position: Int) { - (context as SearchActivity?)!!.onSearchImageClicked(position) + (context as SearchActivity).onSearchImageClicked(position) } override fun notifyViewPager() { diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentContract.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentContract.kt deleted file mode 100644 index 4a26b9d72..000000000 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentContract.kt +++ /dev/null @@ -1,10 +0,0 @@ -package fr.free.nrw.commons.explore.media - -import fr.free.nrw.commons.Media -import fr.free.nrw.commons.explore.PagingContract - - -interface SearchMediaFragmentContract { - interface View : PagingContract.View - interface Presenter : PagingContract.Presenter -} diff --git a/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentPresenter.kt b/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentPresenterImpl.kt similarity index 59% rename from app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentPresenter.kt rename to app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentPresenterImpl.kt index 663624da5..c54e6aaab 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/media/SearchMediaFragmentPresenterImpl.kt @@ -2,13 +2,16 @@ package fr.free.nrw.commons.explore.media import fr.free.nrw.commons.Media import fr.free.nrw.commons.di.CommonsApplicationModule -import fr.free.nrw.commons.explore.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.BasePagingPresenter +import fr.free.nrw.commons.explore.paging.PagingContract import io.reactivex.Scheduler import javax.inject.Inject import javax.inject.Named -class SearchMediaFragmentPresenter @Inject constructor( +interface SearchMediaFragmentPresenter : PagingContract.Presenter + +class SearchMediaFragmentPresenterImpl @Inject constructor( @Named(CommonsApplicationModule.MAIN_THREAD) mainThreadScheduler: Scheduler, dataSourceFactory: PageableMediaDataSource ) : BasePagingPresenter(mainThreadScheduler, dataSourceFactory), - SearchMediaFragmentContract.Presenter + SearchMediaFragmentPresenter diff --git a/app/src/main/java/fr/free/nrw/commons/explore/BasePagingFragment.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt similarity index 98% rename from app/src/main/java/fr/free/nrw/commons/explore/BasePagingFragment.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt index df85e1cc2..fcb7d2ee7 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/BasePagingFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingFragment.kt @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.explore +package fr.free.nrw.commons.explore.paging import android.content.Context import android.content.res.Configuration diff --git a/app/src/main/java/fr/free/nrw/commons/explore/BasePagingPresenter.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingPresenter.kt similarity index 97% rename from app/src/main/java/fr/free/nrw/commons/explore/BasePagingPresenter.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingPresenter.kt index c26d13fba..22194adb8 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/BasePagingPresenter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/BasePagingPresenter.kt @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.explore +package fr.free.nrw.commons.explore.paging import androidx.lifecycle.MutableLiveData import fr.free.nrw.commons.upload.depicts.proxy diff --git a/app/src/main/java/fr/free/nrw/commons/explore/BaseViewHolder.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/BaseViewHolder.kt similarity index 87% rename from app/src/main/java/fr/free/nrw/commons/explore/BaseViewHolder.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/BaseViewHolder.kt index 98115046f..fda1408bf 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/BaseViewHolder.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/BaseViewHolder.kt @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.explore +package fr.free.nrw.commons.explore.paging import android.view.View import androidx.recyclerview.widget.RecyclerView 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/paging/FooterAdapter.kt similarity index 91% rename from app/src/main/java/fr/free/nrw/commons/explore/depictions/FooterAdapter.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/FooterAdapter.kt index 76d4be40a..d166e5145 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/depictions/FooterAdapter.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/FooterAdapter.kt @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.explore.depictions +package fr.free.nrw.commons.explore.paging import android.view.LayoutInflater import android.view.View @@ -26,7 +26,9 @@ class FooterAdapter(private val onRefreshClicked: () -> Unit) : override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (FooterItem.values()[viewType]) { - FooterItem.LoadingItem -> LoadingViewHolder(parent.inflate(R.layout.list_item_progress)) + FooterItem.LoadingItem -> LoadingViewHolder( + parent.inflate(R.layout.list_item_progress) + ) FooterItem.RefreshItem -> RefreshViewHolder( parent.inflate(R.layout.list_item_load_more), onRefreshClicked diff --git a/app/src/main/java/fr/free/nrw/commons/explore/PagingContract.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/PagingContract.kt similarity index 93% rename from app/src/main/java/fr/free/nrw/commons/explore/PagingContract.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/PagingContract.kt index 6bbfa1491..d7169d458 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/PagingContract.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/PagingContract.kt @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.explore +package fr.free.nrw.commons.explore.paging import androidx.lifecycle.LiveData import androidx.paging.PagedList diff --git a/app/src/main/java/fr/free/nrw/commons/explore/PagingDataSource.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/PagingDataSource.kt similarity index 91% rename from app/src/main/java/fr/free/nrw/commons/explore/PagingDataSource.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/PagingDataSource.kt index 9bda6d26f..ed67a71b1 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/PagingDataSource.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/PagingDataSource.kt @@ -1,13 +1,13 @@ -package fr.free.nrw.commons.explore +package fr.free.nrw.commons.explore.paging import androidx.paging.PositionalDataSource -import fr.free.nrw.commons.explore.depictions.LoadFunction +import fr.free.nrw.commons.explore.depictions.search.LoadFunction import io.reactivex.Completable import io.reactivex.processors.PublishProcessor import io.reactivex.schedulers.Schedulers import timber.log.Timber -abstract class SearchDataSource( +abstract class PagingDataSource( private val loadingStates: PublishProcessor ) : PositionalDataSource() { @@ -60,7 +60,7 @@ abstract class SearchDataSource( fun dataSource( loadingStates: PublishProcessor, loadFunction: LoadFunction -) = object : SearchDataSource(loadingStates) { +) = object : PagingDataSource(loadingStates) { override fun getItems(loadSize: Int, startPosition: Int): List { return loadFunction(loadSize, startPosition) } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/PagingDataSourceFactory.kt b/app/src/main/java/fr/free/nrw/commons/explore/paging/PagingDataSourceFactory.kt similarity index 86% rename from app/src/main/java/fr/free/nrw/commons/explore/PagingDataSourceFactory.kt rename to app/src/main/java/fr/free/nrw/commons/explore/paging/PagingDataSourceFactory.kt index 5629ab680..6cce5bcf6 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/PagingDataSourceFactory.kt +++ b/app/src/main/java/fr/free/nrw/commons/explore/paging/PagingDataSourceFactory.kt @@ -1,12 +1,12 @@ -package fr.free.nrw.commons.explore +package fr.free.nrw.commons.explore.paging 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.explore.depictions.LoadFunction -import fr.free.nrw.commons.explore.depictions.LoadingStates +import fr.free.nrw.commons.explore.depictions.search.LoadFunction +import fr.free.nrw.commons.explore.depictions.search.LoadingStates import io.reactivex.Flowable import io.reactivex.processors.PublishProcessor import javax.inject.Inject @@ -18,7 +18,10 @@ abstract class PageableBaseDataSource(private val liveDataConverter: LiveData lateinit var query: String private val dataSourceFactoryFactory: () -> PagingDataSourceFactory = { - dataSourceFactory(_loadingStates, loadFunction) + dataSourceFactory( + _loadingStates, + loadFunction + ) } private val _loadingStates = PublishProcessor.create() val loadingStates: Flowable = _loadingStates @@ -67,11 +70,14 @@ class LiveDataConverter @Inject constructor() { abstract class PagingDataSourceFactory(val loadingStates: LoadingStates) : DataSource.Factory() { - private var currentDataSource: SearchDataSource? = null + private var currentDataSource: PagingDataSource? = null abstract val loadFunction: LoadFunction override fun create() = - dataSource(loadingStates, loadFunction).also { currentDataSource = it } + dataSource( + loadingStates, + loadFunction + ).also { currentDataSource = it } fun retryFailedRequest() { currentDataSource?.retryFailedRequest() 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 0bd70b9ea..2f0968ef4 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 @@ -48,7 +48,7 @@ import fr.free.nrw.commons.category.CategoryDetailsActivity; import fr.free.nrw.commons.contributions.ContributionsFragment; import fr.free.nrw.commons.delete.DeleteHelper; import fr.free.nrw.commons.delete.ReasonBuilder; -import fr.free.nrw.commons.depictions.WikidataItemDetailsActivity; +import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.ui.widget.HtmlTextView; import fr.free.nrw.commons.utils.ViewUtilWrapper; diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java b/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java index d6409fa95..1d010e00a 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/OkHttpJsonApiClient.java @@ -6,7 +6,6 @@ import com.google.gson.Gson; import fr.free.nrw.commons.achievements.FeaturedImages; import fr.free.nrw.commons.achievements.FeedbackResponse; import fr.free.nrw.commons.campaigns.CampaignResponseDTO; -import fr.free.nrw.commons.depictions.subClass.models.SparqlResponse; import fr.free.nrw.commons.explore.depictions.DepictsClient; import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.nearby.Place; @@ -210,16 +209,19 @@ public class OkHttpJsonApiClient { * Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example: * bridge -> suspended bridge, aqueduct, etc */ - public Observable> getChildQIDs(String qid) throws IOException { - return depictedItemsFrom(sparqlQuery(qid, "/queries/subclasses_query.rq")); + public Observable> getChildDepictions(String qid, int startPosition, + int limit) throws IOException { + return depictedItemsFrom(sparqlQuery(qid, startPosition, limit,"/queries/subclasses_query.rq")); } /** * Get the QIDs of all Wikidata items that are subclasses of the given Wikidata item. Example: * bridge -> suspended bridge, aqueduct, etc */ - public Observable> getParentQIDs(String qid) throws IOException { - return depictedItemsFrom(sparqlQuery(qid, "/queries/parentclasses_query.rq")); + public Observable> getParentDepictions(String qid, int startPosition, + int limit) throws IOException { + return depictedItemsFrom(sparqlQuery(qid, startPosition, limit, + "/queries/parentclasses_query.rq")); } private Observable> depictedItemsFrom(Request request) { @@ -231,10 +233,12 @@ public class OkHttpJsonApiClient { } @NotNull - private Request sparqlQuery(String qid, String fileName) throws IOException { - String query = FileUtils.readFromResource(fileName). - replace("${QID}", qid) - .replace("${LANG}", "\"" + Locale.getDefault().getLanguage() + "\""); + private Request sparqlQuery(String qid, int startPosition, int limit, String fileName) throws IOException { + String query = FileUtils.readFromResource(fileName) + .replace("${QID}", qid) + .replace("${LANG}", "\"" + Locale.getDefault().getLanguage() + "\"") + .replace("${LIMIT}",""+ limit) + .replace("${OFFSET}",""+ startPosition); HttpUrl.Builder urlBuilder = HttpUrl .parse(sparqlQueryUrl) .newBuilder() diff --git a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/models/SparqlResponses.kt b/app/src/main/java/fr/free/nrw/commons/mwapi/SparqlResponses.kt similarity index 62% rename from app/src/main/java/fr/free/nrw/commons/depictions/subClass/models/SparqlResponses.kt rename to app/src/main/java/fr/free/nrw/commons/mwapi/SparqlResponses.kt index be9dea64a..84c86bf9f 100644 --- a/app/src/main/java/fr/free/nrw/commons/depictions/subClass/models/SparqlResponses.kt +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/SparqlResponses.kt @@ -1,13 +1,11 @@ -package fr.free.nrw.commons.depictions.subClass.models +package fr.free.nrw.commons.mwapi data class SparqlResponse(val results: Result) data class Result(val bindings: List) data class Binding( - val item: SparqInfo, - val itemLabel: SparqInfo, - val itemDescription: SparqInfo? = null + val item: SparqInfo ) { val id: String get() = item.value.substringAfterLast("/") diff --git a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java index c2c2d82f1..0019206dd 100644 --- a/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/theme/NavigationBaseActivity.java @@ -42,7 +42,7 @@ import fr.free.nrw.commons.auth.LoginActivity; import fr.free.nrw.commons.auth.LogoutClient; import fr.free.nrw.commons.bookmarks.BookmarksActivity; import fr.free.nrw.commons.contributions.MainActivity; -import fr.free.nrw.commons.explore.categories.ExploreActivity; +import fr.free.nrw.commons.explore.ExploreActivity; import fr.free.nrw.commons.kvstore.JsonKvStore; import fr.free.nrw.commons.logging.CommonsLogSender; import fr.free.nrw.commons.review.ReviewActivity; diff --git a/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt b/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt index 1dd28f1fb..21dfa1d72 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/structure/depictions/DepictedItem.kt @@ -1,7 +1,5 @@ package fr.free.nrw.commons.upload.structure.depictions -import fr.free.nrw.commons.explore.depictions.DepictsClient.Companion.getImageUrl -import fr.free.nrw.commons.explore.depictions.THUMB_IMAGE_SIZE import fr.free.nrw.commons.nearby.Place import fr.free.nrw.commons.upload.WikidataItem import fr.free.nrw.commons.wikidata.WikidataProperties @@ -9,8 +7,13 @@ import fr.free.nrw.commons.wikidata.WikidataProperties.* import org.wikipedia.wikidata.DataValue import org.wikipedia.wikidata.Entities import org.wikipedia.wikidata.Statement_partial +import java.math.BigInteger +import java.security.MessageDigest +import java.security.NoSuchAlgorithmException import java.util.* +const val THUMB_IMAGE_SIZE = "70px" + /** * Model class for Depicted Item in Upload and Explore */ @@ -76,3 +79,40 @@ operator fun Entities.Entity.get(property: WikidataProperties) = private fun Map.byLanguageOrFirstOrEmpty() = let { it[Locale.getDefault().language] ?: it.values.firstOrNull() }?.value() ?: "" + +private fun getImageUrl(title: String, size: String): String { + return title.substringAfter(":") + .replace(" ", "_") + .let { + val MD5Hash = getMd5(it) + "https://upload.wikimedia.org/wikipedia/commons/thumb/${MD5Hash[0]}/${MD5Hash[0]}${MD5Hash[1]}/$it/$size-$it" + } +} + +/** + * Generates MD5 hash for the filename + */ +private fun getMd5(input: String): String { + return try { + + // Static getInstance method is called with hashing MD5 + val md = MessageDigest.getInstance("MD5") + + // digest() method is called to calculate message digest + // of an input digest() return array of byte + val messageDigest = md.digest(input.toByteArray()) + + // Convert byte array into signum representation + val no = BigInteger(1, messageDigest) + + // Convert message digest into hex value + var hashtext = no.toString(16) + while (hashtext.length < 32) { + hashtext = "0$hashtext" + } + hashtext + } // For specifying wrong message digest algorithms + catch (e: NoSuchAlgorithmException) { + throw RuntimeException(e) + } +} diff --git a/app/src/main/res/layout/fragment_search_depictions.xml b/app/src/main/res/layout/fragment_search_depictions.xml deleted file mode 100644 index c87bbafcd..000000000 --- a/app/src/main/res/layout/fragment_search_depictions.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - diff --git a/app/src/main/res/xml/shortcuts.xml b/app/src/main/res/xml/shortcuts.xml index cd5f3645f..9c34b6357 100644 --- a/app/src/main/res/xml/shortcuts.xml +++ b/app/src/main/res/xml/shortcuts.xml @@ -10,7 +10,7 @@ tools:targetApi="n_mr1"> diff --git a/app/src/main/resources/queries/parentclasses_query.rq b/app/src/main/resources/queries/parentclasses_query.rq index 0418b5965..30528b172 100644 --- a/app/src/main/resources/queries/parentclasses_query.rq +++ b/app/src/main/resources/queries/parentclasses_query.rq @@ -1,4 +1,5 @@ -SELECT ?item ?itemLabel ?itemDescription WHERE { +SELECT ?item WHERE { wd:${QID} wdt:P279 ?item. - SERVICE wikibase:label { bd:serviceParam wikibase:language ${LANG}. } } +LIMIT ${LIMIT} +OFFSET ${OFFSET} diff --git a/app/src/main/resources/queries/subclasses_query.rq b/app/src/main/resources/queries/subclasses_query.rq index fd4d18b39..0bdab6e6e 100644 --- a/app/src/main/resources/queries/subclasses_query.rq +++ b/app/src/main/resources/queries/subclasses_query.rq @@ -1,4 +1,5 @@ -SELECT ?item ?itemLabel ?itemDescription WHERE { +SELECT ?item WHERE { ?item wdt:P279 wd:${QID}. - SERVICE wikibase:label { bd:serviceParam wikibase:language ${LANG}. } } +LIMIT ${LIMIT} +OFFSET ${OFFSET} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/depictions/SubDepictionListPresenterTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/depictions/SubDepictionListPresenterTest.kt deleted file mode 100644 index fbab051f0..000000000 --- a/app/src/test/kotlin/fr/free/nrw/commons/depictions/SubDepictionListPresenterTest.kt +++ /dev/null @@ -1,70 +0,0 @@ -package fr.free.nrw.commons.depictions - -import fr.free.nrw.commons.depictions.subClass.SubDepictionListContract -import fr.free.nrw.commons.depictions.subClass.SubDepictionListPresenter -import fr.free.nrw.commons.explore.depictions.DepictsClient -import fr.free.nrw.commons.explore.recentsearches.RecentSearchesDao -import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import io.reactivex.Observable -import io.reactivex.schedulers.TestScheduler -import org.junit.Before -import org.junit.Test -import org.mockito.ArgumentMatchers -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.Mockito.verify -import org.mockito.MockitoAnnotations - -class SubDepictionListPresenterTest { - - @Mock - internal lateinit var view: SubDepictionListContract.View - - lateinit var subDepictionListPresenter: SubDepictionListPresenter - - lateinit var testScheduler: TestScheduler - - @Mock - internal lateinit var recentSearchesDao: RecentSearchesDao - - @Mock - internal lateinit var depictsClient: DepictsClient - - @Mock - internal lateinit var okHttpJsonApiClient: OkHttpJsonApiClient - - var testObservable: Observable>? = null - - @Mock - lateinit var depictedItem: DepictedItem - - val depictedItems: ArrayList = ArrayList() - - @Before - @Throws(Exception::class) - fun setUp() { - MockitoAnnotations.initMocks(this) - testScheduler = TestScheduler() - depictedItems.add(depictedItem) - testObservable = Observable.just(depictedItems) - subDepictionListPresenter = SubDepictionListPresenter(recentSearchesDao, depictsClient, okHttpJsonApiClient, testScheduler, testScheduler) - subDepictionListPresenter.onAttachView(view) - } - - @Test - fun initSubDepictionListForParentClass() { - Mockito.`when`(okHttpJsonApiClient.getParentQIDs(ArgumentMatchers.anyString())).thenReturn(testObservable) - subDepictionListPresenter.initSubDepictionList("Q9394", true) - testScheduler.triggerActions() - verify(view)?.onSuccess(depictedItems) - } - - @Test - fun initSubDepictionListForChildClass() { - Mockito.`when`(okHttpJsonApiClient.getChildQIDs(ArgumentMatchers.anyString())).thenReturn(testObservable) - subDepictionListPresenter.initSubDepictionList("Q9394", false) - testScheduler.triggerActions() - verify(view)?.onSuccess(depictedItems) - } -} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/BasePagingPresenterTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/BasePagingPresenterTest.kt index c78e343fb..8f758ead1 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/BasePagingPresenterTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/BasePagingPresenterTest.kt @@ -7,6 +7,7 @@ import com.jraska.livedata.test import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.whenever +import fr.free.nrw.commons.explore.paging.* import io.reactivex.processors.PublishProcessor import io.reactivex.schedulers.TestScheduler import org.junit.Before diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/PageableBaseDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/PageableBaseDataSourceTest.kt index 5e8009ca3..a239a501c 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/PageableBaseDataSourceTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/PageableBaseDataSourceTest.kt @@ -3,7 +3,10 @@ package fr.free.nrw.commons.explore import androidx.lifecycle.LiveData import androidx.paging.PagedList import com.nhaarman.mockitokotlin2.* -import fr.free.nrw.commons.explore.depictions.LoadFunction +import fr.free.nrw.commons.explore.depictions.search.LoadFunction +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.explore.paging.PageableBaseDataSource +import fr.free.nrw.commons.explore.paging.PagingDataSourceFactory import org.junit.Before import org.junit.Ignore import org.junit.Test diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceFactoryTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceFactoryTest.kt index acb38de0d..c11b62afb 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceFactoryTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceFactoryTest.kt @@ -4,6 +4,9 @@ import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.spy import com.nhaarman.mockitokotlin2.verify import fr.free.nrw.commons.explore.depictions.DepictsClient +import fr.free.nrw.commons.explore.paging.LoadingState +import fr.free.nrw.commons.explore.paging.PagingDataSource +import fr.free.nrw.commons.explore.paging.PagingDataSourceFactory import io.reactivex.processors.PublishProcessor import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers.instanceOf @@ -37,7 +40,7 @@ class PagingDataSourceFactoryTest { fun `create returns a dataSource`() { assertThat( factory.create(), - instanceOf(SearchDataSource::class.java) + instanceOf(PagingDataSource::class.java) ) } @@ -45,7 +48,7 @@ class PagingDataSourceFactoryTest { @Ignore("Rewrite with Mockk constructor mocks") fun `retryFailedRequest invokes method if not null`() { val spyFactory = spy(factory) - val dataSource = mock>() + val dataSource = mock>() Mockito.doReturn(dataSource).`when`(spyFactory).create() factory.retryFailedRequest() verify(dataSource).retryFailedRequest() diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/SearchDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceTest.kt similarity index 91% rename from app/src/test/kotlin/fr/free/nrw/commons/explore/SearchDataSourceTest.kt rename to app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceTest.kt index 8254e517d..fb5d2a15a 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/SearchDataSourceTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/PagingDataSourceTest.kt @@ -2,7 +2,9 @@ package fr.free.nrw.commons.explore import androidx.paging.PositionalDataSource import com.nhaarman.mockitokotlin2.* -import fr.free.nrw.commons.explore.depictions.LoadingStates +import fr.free.nrw.commons.explore.depictions.search.LoadingStates +import fr.free.nrw.commons.explore.paging.LoadingState +import fr.free.nrw.commons.explore.paging.PagingDataSource import io.reactivex.plugins.RxJavaPlugins import io.reactivex.processors.PublishProcessor import io.reactivex.schedulers.Schedulers @@ -12,10 +14,10 @@ import org.junit.Test import org.mockito.Mock import org.mockito.MockitoAnnotations -class SearchDataSourceTest { +class PagingDataSourceTest { private lateinit var loadingStates: PublishProcessor - private lateinit var searchDepictionsDataSource: TestSearchDataSource + private lateinit var searchDepictionsDataSource: TestPagingDataSource @Mock private lateinit var mockGetItems: MockGetItems @@ -26,7 +28,7 @@ class SearchDataSourceTest { MockitoAnnotations.initMocks(this) loadingStates = PublishProcessor.create() searchDepictionsDataSource = - TestSearchDataSource( + TestPagingDataSource( loadingStates, mockGetItems ) @@ -109,8 +111,8 @@ class SearchDataSourceTest { } } -class TestSearchDataSource(loadingStates: LoadingStates, val mockGetItems: MockGetItems) : - SearchDataSource(loadingStates) { +class TestPagingDataSource(loadingStates: LoadingStates, val mockGetItems: MockGetItems) : + PagingDataSource(loadingStates) { override fun getItems(loadSize: Int, startPosition: Int): List = mockGetItems.getItems(loadSize, startPosition) } diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSourceTest.kt index df3496c62..510385ebd 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSourceTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/PageableDepictionsDataSourceTest.kt @@ -2,6 +2,7 @@ package fr.free.nrw.commons.explore.depictions import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.whenever +import fr.free.nrw.commons.explore.depictions.search.PageableDepictionsDataSource import io.reactivex.Single import org.hamcrest.MatcherAssert.assertThat import org.hamcrest.Matchers @@ -12,10 +13,14 @@ class PageableDepictionsDataSourceTest { @Test fun `loadFunction loads depictions`() { val depictsClient: DepictsClient = mock() - whenever(depictsClient.searchForDepictions("test", 0, 1)).thenReturn(Single.just(emptyList())) + whenever(depictsClient.searchForDepictions("test", 0, 1)) + .thenReturn(Single.just(emptyList())) val pageableDepictionsDataSource = PageableDepictionsDataSource(mock(), depictsClient) pageableDepictionsDataSource.onQueryUpdated("test") - assertThat(pageableDepictionsDataSource.loadFunction.invoke(0, 1), Matchers.`is`(emptyList())) + assertThat( + pageableDepictionsDataSource.loadFunction.invoke(0, 1), + Matchers.`is`(emptyList()) + ) } } diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceFactoryTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceFactoryTest.kt deleted file mode 100644 index 614b3a5cb..000000000 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceFactoryTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -package fr.free.nrw.commons.explore.depictions - -import com.nhaarman.mockitokotlin2.mock -import com.nhaarman.mockitokotlin2.spy -import com.nhaarman.mockitokotlin2.verify -import io.reactivex.processors.PublishProcessor -import org.hamcrest.MatcherAssert.assertThat -import org.hamcrest.Matchers.`is` -import org.junit.Before -import org.junit.Ignore -import org.junit.Test -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.MockitoAnnotations - -class SearchDepictionsDataSourceFactoryTest { - - @Mock - private lateinit var depictsClient: DepictsClient - - @Mock - private lateinit var loadingStates: PublishProcessor - private lateinit var factory: SearchDepictionsDataSourceFactory - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - factory = SearchDepictionsDataSourceFactory(depictsClient, "test", loadingStates) - } - - @Test - fun `create returns a dataSource`() { - assertThat( - factory.create(), - `is`(SearchDepictionsDataSource(depictsClient, loadingStates, "test")) - ) - } - - @Test - @Ignore("Rewrite with Mockk constructor mocks") - fun `retryFailedRequest invokes method if not null`() { - val spyFactory = spy(factory) - val dataSource = mock() - Mockito.doReturn(dataSource).`when`(spyFactory).create() - factory.retryFailedRequest() - verify(dataSource).retryFailedRequest() - } - - @Test - fun `retryFailedRequest does not invoke method if null`() { - factory.retryFailedRequest() - } -} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceTest.kt deleted file mode 100644 index 50af80ea1..000000000 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchDepictionsDataSourceTest.kt +++ /dev/null @@ -1,106 +0,0 @@ -package fr.free.nrw.commons.explore.depictions - -import androidx.paging.PositionalDataSource -import com.nhaarman.mockitokotlin2.* -import fr.free.nrw.commons.explore.depictions.LoadingState.* -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import io.reactivex.Single -import io.reactivex.plugins.RxJavaPlugins -import io.reactivex.processors.PublishProcessor -import io.reactivex.schedulers.Schedulers -import org.junit.After -import org.junit.Before -import org.junit.Test -import org.mockito.Mock -import org.mockito.MockitoAnnotations - -class SearchDepictionsDataSourceTest { - - @Mock - private lateinit var depictsClient: DepictsClient - - private lateinit var loadingStates: PublishProcessor - private lateinit var searchDepictionsDataSource: SearchDepictionsDataSource - - @Before - fun setUp() { - RxJavaPlugins.setIoSchedulerHandler { Schedulers.trampoline() } - MockitoAnnotations.initMocks(this) - loadingStates = PublishProcessor.create() - searchDepictionsDataSource = - SearchDepictionsDataSource(depictsClient, loadingStates, "test") - } - - @After - fun tearDown() { - RxJavaPlugins.reset() - } - - @Test - fun `loadInitial returns results and emits InitialLoad & Complete`() { - val params = PositionalDataSource.LoadInitialParams(0, 1, 2, false) - val callback = mock>() - whenever(depictsClient.searchForDepictions("test", 1, 0)) - .thenReturn(Single.just(emptyList())) - val testSubscriber = loadingStates.test() - searchDepictionsDataSource.loadInitial(params, callback) - verify(callback).onResult(emptyList(), 0) - testSubscriber.assertValues(InitialLoad, Complete) - } - - @Test - fun `loadInitial onError does not return results and emits InitialLoad & Error`() { - val params = PositionalDataSource.LoadInitialParams(0, 1, 2, false) - val callback = mock>() - whenever(depictsClient.searchForDepictions("test", 1, 0)) - .thenThrow(RuntimeException()) - val testSubscriber = loadingStates.test() - searchDepictionsDataSource.loadInitial(params, callback) - verify(callback, never()).onResult(any(), any()) - testSubscriber.assertValues(InitialLoad, Error) - } - - @Test - fun `loadRange returns results and emits Loading & Complete`() { - val callback: PositionalDataSource.LoadRangeCallback = mock() - val params = PositionalDataSource.LoadRangeParams(0, 1) - whenever(depictsClient.searchForDepictions("test", params.loadSize, params.startPosition)) - .thenReturn(Single.just(emptyList())) - val testSubscriber = loadingStates.test() - searchDepictionsDataSource.loadRange(params, callback) - verify(callback).onResult(emptyList()) - testSubscriber.assertValues(Loading, Complete) - } - - @Test - fun `loadRange onError does not return results and emits Loading & Error`() { - val callback: PositionalDataSource.LoadRangeCallback = mock() - val params = PositionalDataSource.LoadRangeParams(0, 1) - whenever(depictsClient.searchForDepictions("test", params.loadSize, params.startPosition)) - .thenThrow(RuntimeException()) - val testSubscriber = loadingStates.test() - searchDepictionsDataSource.loadRange(params, callback) - verify(callback, never()).onResult(any()) - testSubscriber.assertValues(Loading, Error) - } - - @Test - fun `retryFailedRequest does nothing when null`() { - searchDepictionsDataSource.retryFailedRequest() - verifyNoMoreInteractions(depictsClient) - } - - @Test - fun `retryFailedRequest retries last request`() { - val callback: PositionalDataSource.LoadRangeCallback = mock() - val params = PositionalDataSource.LoadRangeParams(0, 1) - whenever(depictsClient.searchForDepictions("test", params.loadSize, params.startPosition)) - .thenThrow(RuntimeException()).thenReturn(Single.just(emptyList())) - val testSubscriber = loadingStates.test() - searchDepictionsDataSource.loadRange(params, callback) - verify(callback, never()).onResult(any()) - searchDepictionsDataSource.retryFailedRequest() - verify(callback).onResult(emptyList()) - testSubscriber.assertValues(Loading, Error, Loading, Complete) - } -} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactoryTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactoryTest.kt deleted file mode 100644 index 5cabbaf78..000000000 --- a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/SearchableDepictionsDataSourceFactoryTest.kt +++ /dev/null @@ -1,80 +0,0 @@ -package fr.free.nrw.commons.explore.depictions - -import androidx.lifecycle.LiveData -import androidx.paging.PagedList -import com.nhaarman.mockitokotlin2.* -import fr.free.nrw.commons.upload.structure.depictions.DepictedItem -import io.reactivex.processors.PublishProcessor -import org.junit.Before -import org.junit.Test -import org.mockito.Mock -import org.mockito.MockitoAnnotations - -class SearchableDepictionsDataSourceFactoryTest { - - @Mock - private lateinit var searchDepictionsDataSourceFactoryFactory: SearchDepictionsDataSourceFactoryFactory - - @Mock - private lateinit var liveDataConverter: LiveDataConverter - - private lateinit var factory: SearchableDepictionsDataSourceFactory - - - @Before - fun setUp() { - MockitoAnnotations.initMocks(this) - factory = SearchableDepictionsDataSourceFactory( - searchDepictionsDataSourceFactoryFactory, - liveDataConverter - ) - } - - @Test - fun `onQueryUpdated emits new liveData`() { - val (_, liveData) = expectNewLiveData() - factory.searchResults.test() - .also { factory.onQueryUpdated("test") } - .assertValue(liveData) - } - - @Test - fun `onQueryUpdated invokes livedatconverter with no items emitter`() { - val (captor, _) = expectNewLiveData() - factory.onQueryUpdated("test") - factory.noItemsLoadedEvent.test() - .also { captor.firstValue.invoke() } - .assertValue(Unit) - } - - /* - * Just for coverage, no way to really assert this - * */ - @Test - fun `retryFailedRequest does nothing without a factory`() { - factory.retryFailedRequest() - } - - @Test - fun `retryFailedRequest retries with a factory`() { - val (_, _, dataSourceFactory) = expectNewLiveData() - factory.onQueryUpdated("test") - factory.retryFailedRequest() - verify(dataSourceFactory).retryFailedRequest() - } - - private fun expectNewLiveData(): Triple Unit>, LiveData>, SearchDepictionsDataSourceFactory> { - val dataSourceFactory: SearchDepictionsDataSourceFactory = mock() - whenever( - searchDepictionsDataSourceFactoryFactory.create( - "test", - factory.loadingStates as PublishProcessor - ) - ).thenReturn(dataSourceFactory) - val captor = argumentCaptor<() -> Unit>() - val liveData: LiveData> = mock() - whenever(liveDataConverter.convert(eq(dataSourceFactory), captor.capture())) - .thenReturn(liveData) - return Triple(captor, liveData, dataSourceFactory) - } -} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSourceTest.kt new file mode 100644 index 000000000..08a623f96 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/child/PageableChildDepictionsDataSourceTest.kt @@ -0,0 +1,35 @@ +package fr.free.nrw.commons.explore.depictions.child + +import com.nhaarman.mockitokotlin2.whenever +import depictedItem +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient +import io.reactivex.Observable +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.MatcherAssert.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +class PageableChildDepictionsDataSourceTest { + @Mock + lateinit var okHttpJsonApiClient: OkHttpJsonApiClient + @Mock + lateinit var liveDataConverter: LiveDataConverter + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun `loadFunction loads from api at position 0`() { + val dataSource = + PageableChildDepictionsDataSource(liveDataConverter, okHttpJsonApiClient) + dataSource.onQueryUpdated("test") + whenever(okHttpJsonApiClient.getChildDepictions("test", 0, 1)) + .thenReturn(Observable.just(listOf(depictedItem()))) + assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem()))) + } +} diff --git a/app/src/test/kotlin/fr/free/nrw/commons/depictions/Media/PageableDepictedMediaDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/media/PageableDepictedMediaDataSourceTest.kt similarity index 93% rename from app/src/test/kotlin/fr/free/nrw/commons/depictions/Media/PageableDepictedMediaDataSourceTest.kt rename to app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/media/PageableDepictedMediaDataSourceTest.kt index 6e8aa2396..09173f80e 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/depictions/Media/PageableDepictedMediaDataSourceTest.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/media/PageableDepictedMediaDataSourceTest.kt @@ -1,4 +1,4 @@ -package fr.free.nrw.commons.depictions.Media +package fr.free.nrw.commons.explore.depictions.media import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.whenever diff --git a/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSourceTest.kt b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSourceTest.kt new file mode 100644 index 000000000..7e1346854 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/explore/depictions/parent/PageableParentDepictionsDataSourceTest.kt @@ -0,0 +1,37 @@ +package fr.free.nrw.commons.explore.depictions.parent + +import com.nhaarman.mockitokotlin2.whenever +import depictedItem +import fr.free.nrw.commons.explore.paging.LiveDataConverter +import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient +import io.reactivex.Observable +import org.hamcrest.CoreMatchers.`is` +import org.hamcrest.MatcherAssert.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +class PageableParentDepictionsDataSourceTest { + @Mock + lateinit var okHttpJsonApiClient: OkHttpJsonApiClient + + @Mock + lateinit var liveDataConverter: LiveDataConverter + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + } + + @Test + fun `loadFunction loads from api`() { + val dataSource = + PageableParentDepictionsDataSource(liveDataConverter, okHttpJsonApiClient) + dataSource.onQueryUpdated("test") + whenever(okHttpJsonApiClient.getParentDepictions("test", 0, 1)) + .thenReturn(Observable.just(listOf(depictedItem()))) + assertThat(dataSource.loadFunction(1, 0), `is`(listOf(depictedItem()))) + } +} +