From f896287a0d24077c5149dab0e516935bf9db8fed Mon Sep 17 00:00:00 2001 From: VaishSiddharth Date: Thu, 2 Aug 2018 23:29:41 +0530 Subject: [PATCH 1/4] In media search results, rotating screen triggers crash fixed #1753 --- app/src/main/AndroidManifest.xml | 1 + .../java/fr/free/nrw/commons/explore/SearchActivity.java | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 5a96432585..e80e2a84f3 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -114,6 +114,7 @@ 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 f28065eb5e..475b3900a7 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 @@ -1,5 +1,6 @@ package fr.free.nrw.commons.explore; +import android.content.res.Configuration; import android.database.DataSetObserver; import android.os.Bundle; import android.support.design.widget.TabLayout; @@ -194,6 +195,10 @@ public void onSearchImageClicked(int index) { mediaDetails.showImage(index); forceInitBackButton(); } + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } /** * This method is called on Screen Rotation From 36921ac9617f509d55c400e083fdace9d6888e0f Mon Sep 17 00:00:00 2001 From: Ujjwal Agrawal Date: Wed, 8 Aug 2018 01:02:41 +0530 Subject: [PATCH 2/4] Updated API to get Author name too --- .../explore/images/SearchImagesRenderer.java | 4 +-- .../mwapi/ApacheHttpClientMediaWikiApi.java | 32 +++++++++++-------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImagesRenderer.java b/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImagesRenderer.java index 42c044d705..022e8307e2 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImagesRenderer.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImagesRenderer.java @@ -65,11 +65,11 @@ interface ImageClickedListener { */ private void setAuthorView(Media item, TextView author) { if (item.getCreator() != null && !item.getCreator().equals("")) { - author.setVisibility(View.GONE); + author.setVisibility(View.VISIBLE); String uploadedByTemplate = getContext().getString(R.string.image_uploaded_by); author.setText(String.format(uploadedByTemplate, item.getCreator())); } else { - author.setVisibility(View.VISIBLE); + author.setVisibility(View.GONE); } } } diff --git a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java index 2eb3f9b71e..4cf0d82535 100644 --- a/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java +++ b/app/src/main/java/fr/free/nrw/commons/mwapi/ApacheHttpClientMediaWikiApi.java @@ -736,17 +736,21 @@ public List getCategoryImages(String categoryName) { @NonNull public List searchImages(String query, int offset) { List imageNodes = null; + List authorNodes = null; + CustomApiResult customApiResult; try { - imageNodes = api.action("query") + customApiResult= api.action("query") .param("format", "xml") - .param("list", "search") - .param("srwhat", "text") - .param("srnamespace", "6") - .param("srlimit", "25") - .param("sroffset",offset) - .param("srsearch", query) - .get() - .getNodes("/api/query/search/p/@title"); + .param("generator", "search") + .param("gsrwhat", "text") + .param("gsrnamespace", "6") + .param("gsrlimit", "25") + .param("gsroffset",offset) + .param("gsrsearch", query) + .param("prop", "imageinfo") + .get(); + imageNodes= customApiResult.getNodes("/api/query/pages/page/@title"); + authorNodes= customApiResult.getNodes("/api/query/pages/page/imageinfo/ii/@user"); } catch (IOException e) { Timber.e("Failed to obtain searchImages", e); } @@ -756,11 +760,13 @@ public List searchImages(String query, int offset) { } List images = new ArrayList<>(); - for (CustomApiResult imageNode : imageNodes) { - String imgName = imageNode.getDocument().getTextContent(); - images.add(new Media(imgName)); - } + for (int i=0; i< imageNodes.size();i++){ + String imgName = imageNodes.get(i).getDocument().getTextContent(); + Media media = new Media(imgName); + media.setCreator(authorNodes.get(i).getDocument().getTextContent()); + images.add(media); + } return images; } From 2afd3de0f69a43d885e34ef7d762c6dce7f2e7b5 Mon Sep 17 00:00:00 2001 From: Ujjwal Agrawal Date: Wed, 8 Aug 2018 03:37:48 +0530 Subject: [PATCH 3/4] Crash fixed due to notifyDataSetChange --- .../category/CategoryDetailsActivity.java | 20 ++++++++++++ .../category/CategoryImagesActivity.java | 20 ++++++++++++ .../category/CategoryImagesListFragment.java | 25 ++++++++++++++- .../nrw/commons/explore/SearchActivity.java | 21 ++++++++++++ .../explore/images/SearchImageFragment.java | 6 +++- .../media/MediaDetailPagerFragment.java | 32 +++++++++++++++++-- 6 files changed, 120 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java index 3ab3c2c072..fce2fac5ef 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryDetailsActivity.java @@ -250,4 +250,24 @@ public void onBackPressed() { } super.onBackPressed(); } + + /** + * This method is called on success of API call for Images inside a category. + * The viewpager will notified that number of items have changed. + */ + public void viewPagerNotifyDataSetChanged() { + if (mediaDetails!=null){ + mediaDetails.notifyDataSetChanged(); + } + } + + /** + * This method is called when viewPager has reached its end. + * Fetches more images using search query and adds it to the grid view and viewpager adapter + */ + public void requestMoreImages() { + if (categoryImagesListFragment!=null){ + categoryImagesListFragment.fetchMoreImagesViewPager(); + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java index 3821344724..eafc46e682 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesActivity.java @@ -170,6 +170,16 @@ public Media getMediaAtPosition(int i) { } } + /** + * This method is called on success of API call for featured Images. + * The viewpager will notified that number of items have changed. + */ + public void viewPagerNotifyDataSetChanged() { + if (mediaDetails!=null){ + mediaDetails.notifyDataSetChanged(); + } + } + /** * This method is called on from getCount of MediaDetailPagerFragment * The viewpager will contain same number of media items as that of media elements in adapter. @@ -236,4 +246,14 @@ public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } } + + /** + * This method is called when viewPager has reached its end. + * Fetches more images using search query and adds it to the gridView and viewpager adapter + */ + public void requestMoreImages() { + if (categoryImagesListFragment!=null){ + categoryImagesListFragment.fetchMoreImagesViewPager(); + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesListFragment.java b/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesListFragment.java index 385662a054..a78157ee25 100644 --- a/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesListFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/category/CategoryImagesListFragment.java @@ -190,6 +190,20 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun }); } + /** + * This method is called when viewPager has reached its end. + * Fetches more images for the category and adds it to the grid view and viewpager adapter + */ + public void fetchMoreImagesViewPager(){ + if (hasMoreImages && !isLoading) { + isLoading = true; + fetchMoreImages(); + } + if (!hasMoreImages){ + progressBar.setVisibility(GONE); + } + } + /** * Fetches more images for the category and adds it to the grid view adapter */ @@ -228,8 +242,17 @@ private void handleSuccess(List collection) { return; } gridAdapter.addItems(collection); + try { + ((CategoryImagesActivity) getContext()).viewPagerNotifyDataSetChanged(); + }catch (Exception e){ + e.printStackTrace(); + } + try { + ((CategoryDetailsActivity) getContext()).viewPagerNotifyDataSetChanged(); + }catch (Exception e){ + e.printStackTrace(); + } } - progressBar.setVisibility(GONE); isLoading = false; statusTextView.setVisibility(GONE); 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 475b3900a7..38d78fb34e 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 @@ -53,6 +53,7 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai private FragmentManager supportFragmentManager; private MediaDetailPagerFragment mediaDetails; ViewPagerAdapter viewPagerAdapter; + private String query; @Override protected void onCreate(Bundle savedInstanceState) { @@ -104,6 +105,7 @@ public void setTabs() { .debounce(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe( query -> { + this.query = query.toString(); //update image list if (!TextUtils.isEmpty(query)) { viewPager.setVisibility(View.VISIBLE); @@ -145,7 +147,16 @@ public int getTotalMediaCount() { */ @Override public void notifyDatasetChanged() { + } + /** + * This method is called on success of API call for image Search. + * The viewpager will notified that number of items have changed. + */ + public void viewPagerNotifyDataSetChanged() { + if (mediaDetails!=null){ + mediaDetails.notifyDataSetChanged(); + } } /** @@ -245,4 +256,14 @@ public void updateText(String query) { // https://stackoverflow.com/questions/6117967/how-to-remove-focus-without-setting-focus-to-another-control/15481511 viewPager.requestFocus(); } + + /** + * This method is called when viewPager has reached its end. + * Fetches more images using search query and adds it to the recycler view and viewpager adapter + */ + public void requestMoreImages() { + if (searchImageFragment!=null){ + searchImageFragment.addImagesToList(query); + } + } } diff --git a/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java b/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java index a503207e4d..b6c81135f0 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java @@ -13,6 +13,8 @@ import android.view.ViewGroup; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; + import com.pedrogomez.renderers.RVRendererAdapter; import java.util.ArrayList; import java.util.Date; @@ -160,6 +162,7 @@ private void handlePaginationSuccess(List mediaList) { progressBar.setVisibility(View.GONE); imagesAdapter.addAll(mediaList); imagesAdapter.notifyDataSetChanged(); + ((SearchActivity)getContext()).viewPagerNotifyDataSetChanged(); } @@ -179,6 +182,7 @@ private void handleSuccess(List mediaList) { progressBar.setVisibility(View.GONE); imagesAdapter.addAll(mediaList); imagesAdapter.notifyDataSetChanged(); + ((SearchActivity)getContext()).viewPagerNotifyDataSetChanged(); // check if user is waiting for 5 seconds if yes then save search query to history. Handler handler = new Handler(); @@ -239,7 +243,7 @@ public Media getImageAtPosition(int i) { return null; } else { - return new Media(imagesAdapter.getItem(i).getFilename()); + return imagesAdapter.getItem(i); } } } diff --git a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java index fc58ae9900..d5e4fac2f8 100644 --- a/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/media/MediaDetailPagerFragment.java @@ -35,9 +35,12 @@ import fr.free.nrw.commons.Media; import fr.free.nrw.commons.R; import fr.free.nrw.commons.auth.SessionManager; +import fr.free.nrw.commons.category.CategoryDetailsActivity; +import fr.free.nrw.commons.category.CategoryImagesActivity; import fr.free.nrw.commons.contributions.Contribution; import fr.free.nrw.commons.contributions.ContributionsActivity; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; +import fr.free.nrw.commons.explore.SearchActivity; import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.utils.ImageUtils; import timber.log.Timber; @@ -62,6 +65,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple ViewPager pager; private Boolean editable; private boolean isFeaturedImage; + MediaDetailAdapter adapter; public MediaDetailPagerFragment() { this(false, false); @@ -81,7 +85,7 @@ public View onCreateView(LayoutInflater inflater, ButterKnife.bind(this,view); pager.addOnPageChangeListener(this); - final MediaDetailAdapter adapter = new MediaDetailAdapter(getChildFragmentManager()); + adapter = new MediaDetailAdapter(getChildFragmentManager()); if (savedInstanceState != null) { final int pageNumber = savedInstanceState.getInt("current-page"); @@ -269,11 +273,35 @@ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { public void showImage(int i) { Handler handler = new Handler(); - handler.postDelayed(() -> pager.setCurrentItem(i), 10); + handler.postDelayed(() -> pager.setCurrentItem(i), 5); + } + + /** + * The method notify the viewpager that number of items have changed. + */ + public void notifyDataSetChanged(){ + adapter.notifyDataSetChanged(); } @Override public void onPageScrolled(int i, float v, int i2) { + if (i+1 >= adapter.getCount()){ + try{ + ((CategoryImagesActivity) getContext()).requestMoreImages(); + }catch (Exception e){ + e.printStackTrace(); + } + try{ + ((CategoryDetailsActivity) getContext()).requestMoreImages(); + }catch (Exception e){ + e.printStackTrace(); + } + try{ + ((SearchActivity) getContext()).requestMoreImages(); + }catch (Exception e){ + e.printStackTrace(); + } + } getActivity().supportInvalidateOptionsMenu(); } From 919e717b922bf720c903599efed8269cb6b17803 Mon Sep 17 00:00:00 2001 From: Ujjwal Agrawal Date: Wed, 8 Aug 2018 04:12:06 +0530 Subject: [PATCH 4/4] search API duplicate images fixed --- .../commons/explore/images/SearchImageFragment.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java b/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java index b6c81135f0..2c37f04ea0 100644 --- a/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/explore/images/SearchImageFragment.java @@ -158,11 +158,15 @@ public void addImagesToList(String query) { * @param mediaList List of media to be added */ private void handlePaginationSuccess(List mediaList) { - queryList.addAll(mediaList); progressBar.setVisibility(View.GONE); - imagesAdapter.addAll(mediaList); - imagesAdapter.notifyDataSetChanged(); - ((SearchActivity)getContext()).viewPagerNotifyDataSetChanged(); + if (mediaList.size()!=0){ + if (!queryList.get(queryList.size()-1).getFilename().equals(mediaList.get(mediaList.size()-1).getFilename())) { + queryList.addAll(mediaList); + imagesAdapter.addAll(mediaList); + imagesAdapter.notifyDataSetChanged(); + ((SearchActivity)getContext()).viewPagerNotifyDataSetChanged(); + } + } } @@ -197,7 +201,6 @@ private void handleSuccess(List mediaList) { private void handleError(Throwable throwable) { Timber.e(throwable, "Error occurred while loading queried images"); try { - initErrorView(); ViewUtil.showSnackbar(imagesRecyclerView, R.string.error_loading_images); }catch (Exception e){ e.printStackTrace();