diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java
index 3dc79a50b..df50b9cb8 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionViewHolder.java
@@ -1,6 +1,8 @@
package fr.free.nrw.commons.contributions;
import android.view.View;
+import android.widget.Button;
+import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
@@ -13,6 +15,9 @@ class ContributionViewHolder {
final TextView stateView;
final TextView seqNumView;
final ProgressBar progressView;
+ final ImageButton retryButton;
+ final ImageButton cancelButton;
+ int position;
ContributionViewHolder(View parent) {
imageView = parent.findViewById(R.id.contributionImage);
@@ -20,5 +25,8 @@ class ContributionViewHolder {
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);
+ position = 0;
}
}
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java
index 8b43c9f90..fa1d82ae4 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsFragment.java
@@ -332,6 +332,8 @@ public class ContributionsFragment
contributionsListFragment.clearSyncMessage();
notifyAndMigrateDataSetObservers();
+
+ ((ContributionsListAdapter)contributionsListFragment.getAdapter()).setUploadService(uploadService);
}
}
@@ -421,36 +423,6 @@ public class ContributionsFragment
mediaDetailPagerFragment.showImage(i);
}
- /**
- * Retry upload when it is failed
- * @param i position of upload which will be retried
- */
- public void retryUpload(int i) {
- allContributions.moveToPosition(i);
- Contribution c = contributionDao.fromCursor(allContributions);
- if (c.getState() == STATE_FAILED) {
- uploadService.queue(UploadService.ACTION_UPLOAD_FILE, c);
- Timber.d("Restarting for %s", c.toString());
- } else {
- Timber.d("Skipping re-upload for non-failed %s", c.toString());
- }
- }
-
- /**
- * Delete a failed upload attempt
- * @param i position of upload attempt which will be deteled
- */
- public void deleteUpload(int i) {
- allContributions.moveToPosition(i);
- Contribution c = contributionDao.fromCursor(allContributions);
- if (c.getState() == STATE_FAILED) {
- Timber.d("Deleting failed contrib %s", c.toString());
- contributionDao.delete(c);
- } else {
- Timber.d("Skipping deletion for non-failed contrib %s", c.toString());
- }
- }
-
@Override
public void refreshSource() {
getActivity().getSupportLoaderManager().restartLoader(0, null, this);
diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java
index a31caf54f..e26599cbc 100644
--- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java
+++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListAdapter.java
@@ -3,21 +3,33 @@ 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.upload.UploadService;
+import fr.free.nrw.commons.utils.NetworkUtils;
+import fr.free.nrw.commons.utils.ViewUtil;
+import timber.log.Timber;
+
+import static fr.free.nrw.commons.contributions.Contribution.STATE_FAILED;
class ContributionsListAdapter extends CursorAdapter {
private final ContributionDao contributionDao;
+ private UploadService uploadService;
public ContributionsListAdapter(Context context, Cursor c, int flags, ContributionDao contributionDao) {
super(context, c, flags);
this.contributionDao = contributionDao;
}
+ public void setUploadService( UploadService uploadService) {
+ this.uploadService = uploadService;
+ }
+
@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
View parent = LayoutInflater.from(context)
@@ -36,21 +48,29 @@ class ContributionsListAdapter extends CursorAdapter {
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.retryButton.setVisibility(View.GONE);
+ views.cancelButton.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.retryButton.setVisibility(View.GONE);
+ views.cancelButton.setVisibility(View.GONE);
break;
case Contribution.STATE_IN_PROGRESS:
views.stateView.setVisibility(View.GONE);
views.progressView.setVisibility(View.VISIBLE);
+ views.retryButton.setVisibility(View.GONE);
+ views.cancelButton.setVisibility(View.GONE);
long total = contribution.getDataLength();
long transferred = contribution.getTransferred();
if (transferred == 0 || transferred >= total) {
@@ -63,7 +83,63 @@ class ContributionsListAdapter extends CursorAdapter {
views.stateView.setVisibility(View.VISIBLE);
views.stateView.setText(R.string.contribution_state_failed);
views.progressView.setVisibility(View.GONE);
+ views.retryButton.setVisibility(View.VISIBLE);
+ views.cancelButton.setVisibility(View.VISIBLE);
+
+ views.retryButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ retryUpload(cursor);
+ }
+ });
+
+ views.cancelButton.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ deleteUpload(cursor);
+ }
+ });
+
+
break;
}
}
+
+ /**
+ * Retry upload when it is failed
+ * @param cursor cursor will 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());
+ } else {
+ Timber.d("Skipping re-upload for non-failed %s", c.toString());
+ }
+ } else {
+ ViewUtil.showLongToast(mContext,R.string.this_function_needs_network_connection);
+ }
+
+ }
+
+ /**
+ * Delete a failed upload attempt
+ * @param cursor cursor which will 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);
+ } else {
+ Timber.d("Skipping deletion for non-failed contrib %s", c.toString());
+ }
+ } else {
+ ViewUtil.showLongToast(mContext,R.string.this_function_needs_network_connection);
+ }
+
+ }
}
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 76549b207..5b1004be9 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
@@ -189,16 +189,6 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
// Set wallpaper
setWallpaper(m);
return true;
- case R.id.menu_retry_current_image:
- // Retry
- //((MainActivity) getActivity()).retryUpload(pager.getCurrentItem());
- getActivity().getSupportFragmentManager().popBackStack();
- return true;
- case R.id.menu_cancel_current_image:
- // todo: delete image
- //((MainActivity) getActivity()).deleteUpload(pager.getCurrentItem());
- getActivity().getSupportFragmentManager().popBackStack();
- return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -279,8 +269,6 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
Media m = provider.getMediaAtPosition(pager.getCurrentItem());
if (m != null) {
// Enable default set of actions, then re-enable different set of actions only if it is a failed contrib
- menu.findItem(R.id.menu_retry_current_image).setEnabled(false).setVisible(false);
- menu.findItem(R.id.menu_cancel_current_image).setEnabled(false).setVisible(false);
menu.findItem(R.id.menu_browser_current_image).setEnabled(true).setVisible(true);
menu.findItem(R.id.menu_share_current_image).setEnabled(true).setVisible(true);
menu.findItem(R.id.menu_download_current_image).setEnabled(true).setVisible(true);
@@ -297,8 +285,6 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
Contribution c = (Contribution) m;
switch (c.getState()) {
case Contribution.STATE_FAILED:
- menu.findItem(R.id.menu_retry_current_image).setEnabled(true).setVisible(true);
- menu.findItem(R.id.menu_cancel_current_image).setEnabled(true).setVisible(true);
menu.findItem(R.id.menu_browser_current_image).setEnabled(false).setVisible(false);
menu.findItem(R.id.menu_share_current_image).setEnabled(false).setVisible(false);
menu.findItem(R.id.menu_download_current_image).setEnabled(false).setVisible(false);
@@ -306,8 +292,6 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
break;
case Contribution.STATE_IN_PROGRESS:
case Contribution.STATE_QUEUED:
- menu.findItem(R.id.menu_retry_current_image).setEnabled(false).setVisible(false);
- menu.findItem(R.id.menu_cancel_current_image).setEnabled(false).setVisible(false);
menu.findItem(R.id.menu_browser_current_image).setEnabled(false).setVisible(false);
menu.findItem(R.id.menu_share_current_image).setEnabled(false).setVisible(false);
menu.findItem(R.id.menu_download_current_image).setEnabled(false).setVisible(false);
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 8c4c39639..ed56e1c77 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
@@ -8,6 +8,7 @@ import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils;
+import android.util.Log;
import com.google.gson.Gson;
@@ -44,6 +45,7 @@ import java.util.concurrent.Callable;
import fr.free.nrw.commons.BuildConfig;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.PageTitle;
+import fr.free.nrw.commons.R;
import fr.free.nrw.commons.achievements.FeedbackResponse;
import fr.free.nrw.commons.auth.AccountUtil;
import fr.free.nrw.commons.category.CategoryImageUtils;
@@ -52,6 +54,7 @@ import fr.free.nrw.commons.notification.Notification;
import fr.free.nrw.commons.notification.NotificationUtils;
import fr.free.nrw.commons.utils.ContributionUtils;
import fr.free.nrw.commons.utils.DateUtils;
+import fr.free.nrw.commons.utils.ViewUtil;
import in.yuvi.http.fluent.Http;
import io.reactivex.Observable;
import io.reactivex.Single;
@@ -81,6 +84,8 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
private final String WIKIMEDIA_CAMPAIGNS_BASE_URL =
"https://raw.githubusercontent.com/commons-app/campaigns/master/campaigns.json";
+ private final String ERROR_CODE_BAD_TOKEN = "badtoken";
+
public ApacheHttpClientMediaWikiApi(Context context,
String apiURL,
String wikidatApiURL,
@@ -901,6 +906,10 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
if (!resultStatus.equals("Success")) {
String errorCode = result.getString("/api/error/@code");
Timber.e(errorCode);
+
+ if (errorCode.equals(ERROR_CODE_BAD_TOKEN)) {
+ ViewUtil.showLongToast(context, R.string.bad_token_error_proposed_solution);
+ }
return new UploadResult(resultStatus, errorCode);
} else {
// If success we have to remove file from temp directory
diff --git a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
index 0873d46d8..f4a624b18 100644
--- a/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
+++ b/app/src/main/java/fr/free/nrw/commons/upload/UploadService.java
@@ -10,6 +10,7 @@ import android.content.Intent;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
+import android.util.Log;
import android.webkit.MimeTypeMap;
import android.widget.Toast;
diff --git a/app/src/main/res/drawable-hdpi/ic_cancel_white.png b/app/src/main/res/drawable-hdpi/ic_cancel_white.png
new file mode 100644
index 000000000..f8709859d
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_cancel_white.png differ
diff --git a/app/src/main/res/drawable-hdpi/ic_retry_white.png b/app/src/main/res/drawable-hdpi/ic_retry_white.png
new file mode 100644
index 000000000..7664cb010
Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_retry_white.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_cancel_white.png b/app/src/main/res/drawable-mdpi/ic_cancel_white.png
new file mode 100644
index 000000000..2d693927f
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_cancel_white.png differ
diff --git a/app/src/main/res/drawable-mdpi/ic_retry_white.png b/app/src/main/res/drawable-mdpi/ic_retry_white.png
new file mode 100644
index 000000000..b251e128a
Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_retry_white.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_cancel_white.png b/app/src/main/res/drawable-xhdpi/ic_cancel_white.png
new file mode 100644
index 000000000..495fed7ac
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_cancel_white.png differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_retry_white.png b/app/src/main/res/drawable-xhdpi/ic_retry_white.png
new file mode 100644
index 000000000..8526afbda
Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_retry_white.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_cancel_white.png b/app/src/main/res/drawable-xxhdpi/ic_cancel_white.png
new file mode 100644
index 000000000..8c4acd524
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_cancel_white.png differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_retry_white.png b/app/src/main/res/drawable-xxhdpi/ic_retry_white.png
new file mode 100644
index 000000000..3ad498281
Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_retry_white.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_cancel_white.png b/app/src/main/res/drawable-xxxhdpi/ic_cancel_white.png
new file mode 100644
index 000000000..8f131ab24
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_cancel_white.png differ
diff --git a/app/src/main/res/drawable-xxxhdpi/ic_retry_white.png b/app/src/main/res/drawable-xxxhdpi/ic_retry_white.png
new file mode 100644
index 000000000..96046e169
Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_retry_white.png differ
diff --git a/app/src/main/res/layout/layout_contribution.xml b/app/src/main/res/layout/layout_contribution.xml
index b8237b1c2..be9579a02 100644
--- a/app/src/main/res/layout/layout_contribution.xml
+++ b/app/src/main/res/layout/layout_contribution.xml
@@ -28,39 +28,83 @@
-
-
+ android:layout_weight="3"
+ android:layout_gravity="center|bottom"
+ android:orientation="vertical"
+ android:padding="@dimen/small_gap"
+ >
+
-
+
+
+
+
+
+
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:padding="@dimen/small_gap"
+ >
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/fragment_image_detail.xml b/app/src/main/res/menu/fragment_image_detail.xml
index 3161bd155..21f5f9be9 100644
--- a/app/src/main/res/menu/fragment_image_detail.xml
+++ b/app/src/main/res/menu/fragment_image_detail.xml
@@ -25,18 +25,5 @@
android:id="@+id/menu_set_as_wallpaper"
android:title="@string/menu_set_wallpaper"
app:showAsAction="never" />
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 06025e255..653a91450 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -442,4 +442,7 @@ Upload your first media by touching the camera or gallery icon above.
Tap here to see the ongoing campaigns
You won\'t see the campaigns anymore. However, you can re-enable this notification in Settings if you wish.
+ This function requires network connection, please check your connection settings.
+ Upload failed due to issues with edit token. Please try logging out and in again.
+