Skip to content

Commit

Permalink
Feature/refactor contributions (commons-app#3046)
Browse files Browse the repository at this point in the history
* * Refactored ContributionsListFragment to use RecyclerView
* Added ContributionsPresenter
* Extracted out the cursor to presenter
* Probable fix for commons-app#3028

* Improved the logic for cache in ContributionViewHolder

* Some more refactoring

* While displaying images in ContributionsList, check if status is not completed && local uri exists, use that uri to show image

* typo correction in LocalDataSource

* Fixed formatting in ContributionsPresenter

* retain adapter position when orientation changes

* retain child position with its id

* Made ContributionViewHolder not implement ViewHolder

* Code formatting, review suggested changes

* initialise the rv layout managers only when needed

* added test cases for ContributionPresenter

* removed not needed semi colon

* added more java docs and code formatting
  • Loading branch information
ashishkumar468 authored and neslihanturan committed Jul 7, 2019
1 parent 108e28c commit 60b1eb1
Show file tree
Hide file tree
Showing 22 changed files with 810 additions and 588 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,31 +135,4 @@ public int getTotalMediaCount() {
}
return adapter.getMediaAdapter().getCount();
}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void notifyDatasetChanged() {

}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void registerDataSetObserver(DataSetObserver observer) {

}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -173,32 +173,6 @@ public int getTotalMediaCount() {
return categoryImagesListFragment.getAdapter().getCount();
}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void notifyDatasetChanged() {

}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {

}

/**
* This method inflates the menu in the toolbar
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,33 +180,6 @@ public int getTotalMediaCount() {
return categoryImagesListFragment.getAdapter().getCount();
}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void notifyDatasetChanged() {

}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void registerDataSetObserver(DataSetObserver observer) {

}

/**
* This method is never called but it was in MediaDetailProvider Interface
* so it needs to be overrided.
*/
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {

}

/**
* This method inflates the menu in the toolbar
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
package fr.free.nrw.commons.contributions;

import android.content.Context;
import android.net.Uri;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.collection.LruCache;

import com.facebook.drawee.view.SimpleDraweeView;

import org.apache.commons.lang3.StringUtils;

import javax.inject.Inject;
import javax.inject.Named;

import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import com.facebook.drawee.view.SimpleDraweeView;
import fr.free.nrw.commons.MediaDataExtractor;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.ViewHolder;
import fr.free.nrw.commons.contributions.ContributionsListAdapter.Callback;
import fr.free.nrw.commons.contributions.model.DisplayableContribution;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.upload.FileUtils;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.lang3.StringUtils;
import timber.log.Timber;

public class ContributionViewHolder implements ViewHolder<DisplayableContribution> {
public class ContributionViewHolder extends RecyclerView.ViewHolder {

private final Callback callback;
@BindView(R.id.contributionImage)
SimpleDraweeView imageView;
@BindView(R.id.contributionTitle) TextView titleView;
Expand All @@ -47,15 +46,18 @@ public class ContributionViewHolder implements ViewHolder<DisplayableContributio

private DisplayableContribution contribution;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private int position;

ContributionViewHolder(View parent) {
ContributionViewHolder(View parent, Callback callback) {
super(parent);
ButterKnife.bind(this, parent);
this.callback=callback;
}

@Override
public void bindModel(Context context, DisplayableContribution contribution) {
ApplicationlessInjection.getInstance(context)
public void init(int position, DisplayableContribution contribution) {
ApplicationlessInjection.getInstance(itemView.getContext())
.getCommonsApplicationComponent().inject(this);
this.position=position;
this.contribution = contribution;
fetchAndDisplayThumbnail(contribution);
titleView.setText(contribution.getDisplayTitle());
Expand Down Expand Up @@ -104,19 +106,39 @@ public void bindModel(Context context, DisplayableContribution contribution) {
* @param contribution
*/
private void fetchAndDisplayThumbnail(DisplayableContribution contribution) {
if (!StringUtils.isBlank(thumbnailCache.get(contribution.getFilename()))) {
imageView.setImageURI(thumbnailCache.get(contribution.getFilename()));
String keyForLRUCache = getKeyForLRUCache(contribution.getContentUri());
String cacheUrl = thumbnailCache.get(keyForLRUCache);
if (!StringUtils.isBlank(cacheUrl)) {
imageView.setImageURI(cacheUrl);
return;
}
Timber.d("Fetching thumbnail for %s", contribution.getFilename());
Disposable disposable = mediaDataExtractor.getMediaFromFileName(contribution.getFilename())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(media -> {
thumbnailCache.put(contribution.getFilename(), media.getThumbUrl());
imageView.setImageURI(media.getThumbUrl());
});
compositeDisposable.add(disposable);

imageView.setBackground(null);
if ((contribution.getState() != Contribution.STATE_COMPLETED) && FileUtils.fileExists(
contribution.getLocalUri())) {
imageView.setImageURI(contribution.getLocalUri());
} else {
Timber.d("Fetching thumbnail for %s", contribution.getFilename());
Disposable disposable = mediaDataExtractor
.getMediaFromFileName(contribution.getFilename())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(media -> {
thumbnailCache.put(keyForLRUCache, media.getThumbUrl());
imageView.setImageURI(media.getThumbUrl());
});
compositeDisposable.add(disposable);
}

}

/**
* Returns image key for the LRU cache, basically the id of the image, (the content uri is the ""+/id)
* @param contentUri
* @return
*/
private String getKeyForLRUCache(Uri contentUri) {
return contentUri.getLastPathSegment();
}

public void clear() {
Expand All @@ -128,28 +150,19 @@ public void clear() {
*/
@OnClick(R.id.retryButton)
public void retryUpload() {
DisplayableContribution.ContributionActions actions = contribution.getContributionActions();
if (actions != null) {
actions.retryUpload();
}
callback.retryUpload(contribution);
}

/**
* Delete a failed upload attempt
*/
@OnClick(R.id.cancelButton)
public void deleteUpload() {
DisplayableContribution.ContributionActions actions = contribution.getContributionActions();
if (actions != null) {
actions.deleteUpload();
}
callback.deleteUpload(contribution);
}

@OnClick(R.id.contributionImage)
public void imageClicked(){
DisplayableContribution.ContributionActions actions = contribution.getContributionActions();
if (actions != null) {
actions.onClick();
}
callback.openMediaDetail(position);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package fr.free.nrw.commons.contributions;

import android.database.Cursor;
import androidx.loader.app.LoaderManager;
import fr.free.nrw.commons.BasePresenter;
import fr.free.nrw.commons.Media;

/**
* The contract for Contributions View & Presenter
*/
public class ContributionsContract {

public interface View {

void showWelcomeTip(boolean numberOfUploads);

void showProgress(boolean shouldShow);

void showNoContributionsUI(boolean shouldShow);

void setUploadCount(int count);

void onDataSetChanged();
}

public interface UserActionListener extends BasePresenter<ContributionsContract.View>,
LoaderManager.LoaderCallbacks<Cursor> {

Contribution getContributionsFromCursor(Cursor cursor);

void deleteUpload(Contribution contribution);

Media getItemAtPosition(int i);
}
}
Loading

0 comments on commit 60b1eb1

Please sign in to comment.