mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Use viewholder for populating contributions list (#2306)
* Use viewholder for populatiing contributions list * Fix codacy issues * Remove unused code
This commit is contained in:
parent
2ba6ed622f
commit
35f1e84ff1
6 changed files with 187 additions and 123 deletions
|
|
@ -1,35 +1,96 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import fr.free.nrw.commons.MediaWikiImageView;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.ViewHolder;
|
||||
import fr.free.nrw.commons.contributions.model.DisplayableContribution;
|
||||
|
||||
class ContributionViewHolder {
|
||||
final MediaWikiImageView imageView;
|
||||
final TextView titleView;
|
||||
final TextView stateView;
|
||||
final TextView seqNumView;
|
||||
final ProgressBar progressView;
|
||||
final ImageButton retryButton;
|
||||
final ImageButton cancelButton;
|
||||
final LinearLayout failedImageOptions;
|
||||
int position;
|
||||
class ContributionViewHolder implements ViewHolder<DisplayableContribution> {
|
||||
@BindView(R.id.contributionImage) MediaWikiImageView imageView;
|
||||
@BindView(R.id.contributionTitle) TextView titleView;
|
||||
@BindView(R.id.contributionState) TextView stateView;
|
||||
@BindView(R.id.contributionSequenceNumber) TextView seqNumView;
|
||||
@BindView(R.id.contributionProgress) ProgressBar progressView;
|
||||
@BindView(R.id.failed_image_options) LinearLayout failedImageOptions;
|
||||
|
||||
private DisplayableContribution contribution;
|
||||
|
||||
ContributionViewHolder(View parent) {
|
||||
imageView = parent.findViewById(R.id.contributionImage);
|
||||
titleView = parent.findViewById(R.id.contributionTitle);
|
||||
stateView = parent.findViewById(R.id.contributionState);
|
||||
seqNumView = parent.findViewById(R.id.contributionSequenceNumber);
|
||||
progressView = parent.findViewById(R.id.contributionProgress);
|
||||
retryButton = parent.findViewById(R.id.retryButton);
|
||||
cancelButton = parent.findViewById(R.id.cancelButton);
|
||||
failedImageOptions=parent.findViewById(R.id.failed_image_options);
|
||||
position = 0;
|
||||
ButterKnife.bind(this, parent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindModel(Context context, DisplayableContribution contribution) {
|
||||
this.contribution = contribution;
|
||||
imageView.setMedia(contribution);
|
||||
titleView.setText(contribution.getDisplayTitle());
|
||||
|
||||
seqNumView.setText(String.valueOf(contribution.getPosition() + 1));
|
||||
seqNumView.setVisibility(View.VISIBLE);
|
||||
|
||||
switch (contribution.getState()) {
|
||||
case Contribution.STATE_COMPLETED:
|
||||
stateView.setVisibility(View.GONE);
|
||||
progressView.setVisibility(View.GONE);
|
||||
failedImageOptions.setVisibility(View.GONE);
|
||||
stateView.setText("");
|
||||
break;
|
||||
case Contribution.STATE_QUEUED:
|
||||
stateView.setVisibility(View.VISIBLE);
|
||||
progressView.setVisibility(View.GONE);
|
||||
stateView.setText(R.string.contribution_state_queued);
|
||||
failedImageOptions.setVisibility(View.GONE);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
stateView.setVisibility(View.GONE);
|
||||
progressView.setVisibility(View.VISIBLE);
|
||||
failedImageOptions.setVisibility(View.GONE);
|
||||
long total = contribution.getDataLength();
|
||||
long transferred = contribution.getTransferred();
|
||||
if (transferred == 0 || transferred >= total) {
|
||||
progressView.setIndeterminate(true);
|
||||
} else {
|
||||
progressView.setProgress((int)(((double)transferred / (double)total) * 100));
|
||||
}
|
||||
break;
|
||||
case Contribution.STATE_FAILED:
|
||||
stateView.setVisibility(View.VISIBLE);
|
||||
stateView.setText(R.string.contribution_state_failed);
|
||||
progressView.setVisibility(View.GONE);
|
||||
failedImageOptions.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry upload when it is failed
|
||||
*/
|
||||
@OnClick(R.id.retryButton)
|
||||
public void retryUpload() {
|
||||
DisplayableContribution.ContributionActions actions = contribution.getContributionActions();
|
||||
if (actions != null) {
|
||||
actions.retryUpload();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a failed upload attempt
|
||||
*/
|
||||
@OnClick(R.id.cancelButton)
|
||||
public void deleteUpload() {
|
||||
DisplayableContribution.ContributionActions actions = contribution.getContributionActions();
|
||||
if (actions != null) {
|
||||
actions.deleteUpload();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,31 +84,25 @@ public class ContributionsFragment
|
|||
ContributionsListFragment.SourceRefresher,
|
||||
LocationUpdateListener,ICampaignsView
|
||||
{
|
||||
@Inject
|
||||
@Named("default_preferences")
|
||||
BasicKvStore defaultKvStore;
|
||||
@Inject
|
||||
ContributionDao contributionDao;
|
||||
@Inject
|
||||
MediaWikiApi mediaWikiApi;
|
||||
@Inject
|
||||
NotificationController notificationController;
|
||||
@Inject
|
||||
NearbyController nearbyController;
|
||||
@Inject @Named("default_preferences") BasicKvStore defaultKvStore;
|
||||
@Inject ContributionDao contributionDao;
|
||||
@Inject MediaWikiApi mediaWikiApi;
|
||||
@Inject NotificationController notificationController;
|
||||
@Inject NearbyController nearbyController;
|
||||
|
||||
private ArrayList<DataSetObserver> observersWaitingForLoad = new ArrayList<>();
|
||||
private Cursor allContributions;
|
||||
private UploadService uploadService;
|
||||
private boolean isUploadServiceConnected;
|
||||
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||
CountDownLatch waitForContributionsListFragment = new CountDownLatch(1);
|
||||
|
||||
private ContributionsListFragment contributionsListFragment;
|
||||
private MediaDetailPagerFragment mediaDetailPagerFragment;
|
||||
public static final String CONTRIBUTION_LIST_FRAGMENT_TAG = "ContributionListFragmentTag";
|
||||
public static final String MEDIA_DETAIL_PAGER_FRAGMENT_TAG = "MediaDetailFragmentTag";
|
||||
|
||||
public NearbyNotificationCardView nearbyNotificationCardView;
|
||||
@BindView(R.id.card_view_nearby) public NearbyNotificationCardView nearbyNotificationCardView;
|
||||
@BindView(R.id.campaigns_view) CampaignView campaignView;
|
||||
|
||||
private Disposable placesDisposable;
|
||||
private LatLng curLatLng;
|
||||
|
||||
|
|
@ -120,10 +114,7 @@ public class ContributionsFragment
|
|||
private CheckBox checkBox;
|
||||
private CampaignsPresenter presenter;
|
||||
|
||||
|
||||
@BindView(R.id.campaigns_view) CampaignView campaignView;
|
||||
|
||||
/**
|
||||
/**
|
||||
* Since we will need to use parent activity on onAuthCookieAcquired, we have to wait
|
||||
* fragment to be attached. Latch will be responsible for this sync.
|
||||
*/
|
||||
|
|
@ -159,7 +150,6 @@ public class ContributionsFragment
|
|||
presenter = new CampaignsPresenter();
|
||||
presenter.onAttachView(this);
|
||||
campaignView.setVisibility(View.GONE);
|
||||
nearbyNotificationCardView = view.findViewById(R.id.card_view_nearby);
|
||||
checkBoxView = View.inflate(getActivity(), R.layout.nearby_permission_dialog, null);
|
||||
checkBox = (CheckBox) checkBoxView.findViewById(R.id.never_ask_again);
|
||||
checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
|
||||
|
|
@ -359,7 +349,6 @@ public class ContributionsFragment
|
|||
if (getActivity() != null) { // If fragment is attached to parent activity
|
||||
getActivity().bindService(uploadServiceIntent, uploadServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
isUploadServiceConnected = true;
|
||||
allContributions = contributionDao.loadAllContributions();
|
||||
getActivity().getSupportLoaderManager().initLoader(0, null, ContributionsFragment.this);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ package fr.free.nrw.commons.contributions;
|
|||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.support.v4.widget.CursorAdapter;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.model.DisplayableContribution;
|
||||
import fr.free.nrw.commons.upload.UploadService;
|
||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
|
|
@ -20,13 +20,18 @@ class ContributionsListAdapter extends CursorAdapter {
|
|||
|
||||
private final ContributionDao contributionDao;
|
||||
private UploadService uploadService;
|
||||
private Context context;
|
||||
|
||||
public ContributionsListAdapter(Context context, Cursor c, int flags, ContributionDao contributionDao) {
|
||||
public ContributionsListAdapter(Context context,
|
||||
Cursor c,
|
||||
int flags,
|
||||
ContributionDao contributionDao) {
|
||||
super(context, c, flags);
|
||||
this.context = context;
|
||||
this.contributionDao = contributionDao;
|
||||
}
|
||||
|
||||
public void setUploadService( UploadService uploadService) {
|
||||
public void setUploadService(UploadService uploadService) {
|
||||
this.uploadService = uploadService;
|
||||
}
|
||||
|
||||
|
|
@ -43,98 +48,55 @@ class ContributionsListAdapter extends CursorAdapter {
|
|||
final ContributionViewHolder views = (ContributionViewHolder)view.getTag();
|
||||
final Contribution contribution = contributionDao.fromCursor(cursor);
|
||||
|
||||
views.imageView.setMedia(contribution);
|
||||
views.titleView.setText(contribution.getDisplayTitle());
|
||||
|
||||
views.seqNumView.setText(String.valueOf(cursor.getPosition() + 1));
|
||||
views.seqNumView.setVisibility(View.VISIBLE);
|
||||
views.position = cursor.getPosition();
|
||||
|
||||
|
||||
switch (contribution.getState()) {
|
||||
case Contribution.STATE_COMPLETED:
|
||||
views.stateView.setVisibility(View.GONE);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.failedImageOptions.setVisibility(View.GONE);
|
||||
views.stateView.setText("");
|
||||
break;
|
||||
case Contribution.STATE_QUEUED:
|
||||
views.stateView.setVisibility(View.VISIBLE);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.stateView.setText(R.string.contribution_state_queued);
|
||||
views.failedImageOptions.setVisibility(View.GONE);
|
||||
break;
|
||||
case Contribution.STATE_IN_PROGRESS:
|
||||
views.stateView.setVisibility(View.GONE);
|
||||
views.progressView.setVisibility(View.VISIBLE);
|
||||
views.failedImageOptions.setVisibility(View.GONE);
|
||||
long total = contribution.getDataLength();
|
||||
long transferred = contribution.getTransferred();
|
||||
if (transferred == 0 || transferred >= total) {
|
||||
views.progressView.setIndeterminate(true);
|
||||
} else {
|
||||
views.progressView.setProgress((int)(((double)transferred / (double)total) * 100));
|
||||
}
|
||||
break;
|
||||
case Contribution.STATE_FAILED:
|
||||
views.stateView.setVisibility(View.VISIBLE);
|
||||
views.stateView.setText(R.string.contribution_state_failed);
|
||||
views.progressView.setVisibility(View.GONE);
|
||||
views.failedImageOptions.setVisibility(View.VISIBLE);
|
||||
|
||||
views.retryButton.setOnClickListener(new View.OnClickListener() {
|
||||
DisplayableContribution displayableContribution = new DisplayableContribution(contribution,
|
||||
cursor.getPosition(),
|
||||
new DisplayableContribution.ContributionActions() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
retryUpload(cursor);
|
||||
public void retryUpload() {
|
||||
ContributionsListAdapter.this.retryUpload(contribution);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUpload() {
|
||||
ContributionsListAdapter.this.deleteUpload(contribution);
|
||||
}
|
||||
});
|
||||
|
||||
views.cancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
deleteUpload(cursor);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
views.bindModel(context, displayableContribution);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry upload when it is failed
|
||||
* @param cursor cursor will be retried
|
||||
* @param contribution contribution to be retried
|
||||
*/
|
||||
public void retryUpload(Cursor cursor) {
|
||||
if (NetworkUtils.isInternetConnectionEstablished(mContext)) {
|
||||
Contribution c = contributionDao.fromCursor(cursor);
|
||||
if (c.getState() == STATE_FAILED) {
|
||||
uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c);
|
||||
Timber.d("Restarting for %s", c.toString());
|
||||
private void retryUpload(Contribution contribution) {
|
||||
if (NetworkUtils.isInternetConnectionEstablished(context)) {
|
||||
if (contribution.getState() == STATE_FAILED
|
||||
&& uploadService!= null) {
|
||||
uploadService.queue(UploadService.ACTION_UPLOAD_FILE, contribution);
|
||||
Timber.d("Restarting for %s", contribution.toString());
|
||||
} else {
|
||||
Timber.d("Skipping re-upload for non-failed %s", c.toString());
|
||||
Timber.d("Skipping re-upload for non-failed %s", contribution.toString());
|
||||
}
|
||||
} else {
|
||||
ViewUtil.showLongToast(mContext,R.string.this_function_needs_network_connection);
|
||||
ViewUtil.showLongToast(context, R.string.this_function_needs_network_connection);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a failed upload attempt
|
||||
* @param cursor cursor which will be deleted
|
||||
* @param contribution contribution to be deleted
|
||||
*/
|
||||
public void deleteUpload(Cursor cursor) {
|
||||
if (NetworkUtils.isInternetConnectionEstablished(mContext)) {
|
||||
Contribution c = contributionDao.fromCursor(cursor);
|
||||
if (c.getState() == STATE_FAILED) {
|
||||
Timber.d("Deleting failed contrib %s", c.toString());
|
||||
contributionDao.delete(c);
|
||||
private void deleteUpload(Contribution contribution) {
|
||||
if (NetworkUtils.isInternetConnectionEstablished(context)) {
|
||||
if (contribution.getState() == STATE_FAILED) {
|
||||
Timber.d("Deleting failed contrib %s", contribution.toString());
|
||||
contributionDao.delete(contribution);
|
||||
} else {
|
||||
Timber.d("Skipping deletion for non-failed contrib %s", c.toString());
|
||||
Timber.d("Skipping deletion for non-failed contrib %s", contribution.toString());
|
||||
}
|
||||
} else {
|
||||
ViewUtil.showLongToast(mContext,R.string.this_function_needs_network_connection);
|
||||
ViewUtil.showLongToast(context, R.string.this_function_needs_network_connection);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
package fr.free.nrw.commons.contributions;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
|
|
@ -121,13 +119,6 @@ public class ContributionsListFragment extends CommonsDaggerSupportFragment {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
ContributionsFragment parentFragment = (ContributionsFragment)getParentFragment();
|
||||
parentFragment.waitForContributionsListFragment.countDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Responsible to set progress bar invisible and visible
|
||||
* @param isVisible True when contributions list should be hidden.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package fr.free.nrw.commons.contributions.model;
|
||||
|
||||
import fr.free.nrw.commons.contributions.Contribution;
|
||||
|
||||
public class DisplayableContribution extends Contribution {
|
||||
private int position;
|
||||
private ContributionActions contributionActions;
|
||||
|
||||
private DisplayableContribution(Contribution contribution,
|
||||
int position) {
|
||||
super(contribution.getContentUri(),
|
||||
contribution.getFilename(),
|
||||
contribution.getLocalUri(),
|
||||
contribution.getImageUrl(),
|
||||
contribution.getDateCreated(),
|
||||
contribution.getState(),
|
||||
contribution.getDataLength(),
|
||||
contribution.getDateUploaded(),
|
||||
contribution.getTransferred(),
|
||||
contribution.getSource(),
|
||||
contribution.getDescription(),
|
||||
contribution.getCreator(),
|
||||
contribution.getMultiple(),
|
||||
contribution.getWidth(),
|
||||
contribution.getHeight(),
|
||||
contribution.getLicense());
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public DisplayableContribution(Contribution contribution,
|
||||
int position,
|
||||
ContributionActions contributionActions) {
|
||||
this(contribution, position);
|
||||
this.contributionActions = contributionActions;
|
||||
}
|
||||
|
||||
public int getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public void setPosition(int position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public ContributionActions getContributionActions() {
|
||||
return contributionActions;
|
||||
}
|
||||
|
||||
public interface ContributionActions {
|
||||
void retryUpload();
|
||||
|
||||
void deleteUpload();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package fr.free.nrw.commons.widget;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
public interface ViewHolder<T> {
|
||||
void bindModel(Context context, T model);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue