Brion VIBBER has submitted this change and it was merged. Change subject: Handle Captchas returned when editing ......................................................................
Handle Captchas returned when editing - Captcha needs to be scaled up. Picasso has an issue with reading our captcha images for some reason if we try to resize them: https://github.com/square/picasso/issues/249#issuecomment-33259920 This will need to be worked around Change-Id: Iadce6af2f1dc66bcf41adc19363ca4d28ce56971 --- M wikipedia/res/layout/activity_edit_section.xml M wikipedia/res/values/strings.xml M wikipedia/src/main/java/org/wikipedia/editing/CaptchaEditResult.java M wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java M wikipedia/src/main/java/org/wikipedia/editing/EditingResult.java M wikipedia/src/main/java/org/wikipedia/editing/SuccessEditResult.java 6 files changed, 179 insertions(+), 5 deletions(-) Approvals: Brion VIBBER: Verified; Looks good to me, approved diff --git a/wikipedia/res/layout/activity_edit_section.xml b/wikipedia/res/layout/activity_edit_section.xml index 3720921..8c9a3c6 100644 --- a/wikipedia/res/layout/activity_edit_section.xml +++ b/wikipedia/res/layout/activity_edit_section.xml @@ -45,4 +45,35 @@ /> </LinearLayout> + <LinearLayout + android:id="@+id/edit_section_captcha_container" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:background="@android:color/background_light" + android:orientation="vertical" + android:visibility="gone" + > + <TextView android:layout_width="match_parent" android:layout_height="wrap_content" + android:text="@string/edit_section_captcha_message" + style="?android:textAppearanceMedium" + android:layout_margin="16dp" + /> + <ImageView + android:id="@+id/edit_section_captcha_image" + android:layout_gravity="center_horizontal" + android:layout_width="wrap_content" + android:scaleType="centerInside" + android:layout_height="wrap_content" + /> + <EditText android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_margin="16dp" + style="?android:textAppearanceMedium" + android:layout_gravity="center_horizontal" + android:id="@+id/edit_section_captcha_text" + android:hint="@string/edit_section_captcha_hint" + android:padding="8dp" + /> + + </LinearLayout> </FrameLayout> \ No newline at end of file diff --git a/wikipedia/res/values/strings.xml b/wikipedia/res/values/strings.xml index e4acfdc..4b5a304 100644 --- a/wikipedia/res/values/strings.xml +++ b/wikipedia/res/values/strings.xml @@ -53,4 +53,9 @@ <string name="dialog_message_edit_failed_cancel">Cancel</string> <string name="menu_show_toc">Table of Contents</string> <string name="search_no_results_found">No results found</string> + <string name="edit_section_captcha_message">To help protect against automated spam, please enter the words that + appear below + </string> + <string name="edit_section_captcha_hint">Repeat words from above</string> + <string name="edit_section_title_captcha">Enter captcha</string> </resources> \ No newline at end of file diff --git a/wikipedia/src/main/java/org/wikipedia/editing/CaptchaEditResult.java b/wikipedia/src/main/java/org/wikipedia/editing/CaptchaEditResult.java index f4bdeb4..0faa3a2 100644 --- a/wikipedia/src/main/java/org/wikipedia/editing/CaptchaEditResult.java +++ b/wikipedia/src/main/java/org/wikipedia/editing/CaptchaEditResult.java @@ -1,5 +1,7 @@ package org.wikipedia.editing; +import android.os.Parcel; +import android.os.Parcelable; import org.wikipedia.Site; // Handles only Image Captchas @@ -13,6 +15,12 @@ this.captchaPath = captchaPath; } + protected CaptchaEditResult(Parcel in) { + super(in); + captchaId = in.readString(); + captchaPath = in.readString(); + } + public String getCaptchaId() { return captchaId; } @@ -20,4 +28,23 @@ public String getCaptchaUrl(Site site) { return site.getFullUrl(captchaPath); } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags); + dest.writeString(captchaId); + dest.writeString(captchaPath); + } + + public static final Parcelable.Creator<CaptchaEditResult> CREATOR + = new Parcelable.Creator<CaptchaEditResult>() { + public CaptchaEditResult createFromParcel(Parcel in) { + return new CaptchaEditResult(in); + } + + public CaptchaEditResult[] newArray(int size) { + return new CaptchaEditResult[size]; + } + }; + } diff --git a/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java b/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java index 2894bc2..b3afc6e 100644 --- a/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java +++ b/wikipedia/src/main/java/org/wikipedia/editing/EditSectionActivity.java @@ -4,15 +4,20 @@ import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.DialogInterface; +import android.graphics.Bitmap; +import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; -import android.widget.Button; -import android.widget.EditText; -import android.widget.Toast; +import android.widget.*; import com.github.kevinsawicki.http.HttpRequest; +import com.squareup.picasso.Callback; +import com.squareup.picasso.Picasso; +import com.squareup.picasso.Transformation; +import org.mediawiki.api.json.Api; +import org.mediawiki.api.json.RequestBuilder; import org.wikipedia.PageTitle; import org.wikipedia.R; import org.wikipedia.Utils; @@ -34,6 +39,12 @@ private View sectionContainer; private View sectionError; private Button sectionErrorRetry; + private View captchaContainer; + private ImageView captchaImage; + private EditText captchaText; + private Button captchaConfirm; + + private CaptchaEditResult captchaEditResult; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -48,6 +59,8 @@ title = getIntent().getParcelableExtra(EXTRA_TITLE); section = getIntent().getParcelableExtra(EXTRA_SECTION); + progressDialog = new ProgressDialog(this); + getActionBar().setTitle(getString(R.string.editsection_activity_title)); sectionText = (EditText) findViewById(R.id.edit_section_text); @@ -56,8 +69,17 @@ sectionError = findViewById(R.id.edit_section_error); sectionErrorRetry = (Button) findViewById(R.id.edit_section_error_retry); + captchaContainer = findViewById(R.id.edit_section_captcha_container); + captchaImage = (ImageView) findViewById(R.id.edit_section_captcha_image); + captchaText = (EditText) findViewById(R.id.edit_section_captcha_text); + if (savedInstanceState != null && savedInstanceState.containsKey("sectionWikitext")) { sectionWikitext = savedInstanceState.getString("sectionWikitext"); + } + + if (savedInstanceState != null && savedInstanceState.containsKey("captcha")) { + captchaEditResult = savedInstanceState.getParcelable("captcha"); + handleCaptcha(); } sectionErrorRetry.setOnClickListener(new View.OnClickListener() { @@ -71,15 +93,29 @@ fetchSectionText(); } + private ProgressDialog progressDialog; private void doSave() { - final ProgressDialog progressDialog = new ProgressDialog(this); progressDialog.setIndeterminate(true); progressDialog.setCancelable(false); progressDialog.setMessage(getString(R.string.dialog_saving_in_progress)); + if (captchaEditResult != null) { + // Show the wikitext in the background when captcha is being saved= + Utils.crossFade(captchaContainer, sectionContainer); + } new DoEditTask(this, title, sectionText.getText().toString(), section.getId()) { @Override public void onBeforeExecute() { progressDialog.show(); + } + + @Override + public RequestBuilder buildRequest(Api api) { + RequestBuilder builder = super.buildRequest(api); + if (captchaEditResult != null) { + builder.param("captchaid", captchaEditResult.getCaptchaId()) + .param("captchaword", captchaText.getText().toString()); + } + return builder; } @Override @@ -115,6 +151,9 @@ setResult(EditHandler.RESULT_REFRESH_PAGE); Toast.makeText(EditSectionActivity.this, R.string.edit_saved_successfully, Toast.LENGTH_LONG).show(); finish(); + } else if (result instanceof CaptchaEditResult) { + captchaEditResult = (CaptchaEditResult) result; + handleCaptcha(); } else { // Expand to do everything. onCatch(null); @@ -122,7 +161,35 @@ } }.execute(); + } + private void handleCaptcha() { + Picasso.with(EditSectionActivity.this) + .load(Uri.parse(captchaEditResult.getCaptchaUrl(title.getSite()))) + // Don't use .fit() here - seems to cause the loading to fail + // See https://github.com/square/picasso/issues/249 + .into(captchaImage, new Callback() { + @Override + public void onSuccess() { + getActionBar().setTitle(R.string.edit_section_title_captcha); + progressDialog.hide(); + + // In case there was a captcha attempt before + captchaText.setText(""); + Utils.crossFade(sectionContainer, captchaContainer); + } + + @Override + public void onError() { + } + }); + } + + private void cancelCaptcha() { + captchaEditResult = null; + captchaText.setText(""); + getActionBar().setTitle(R.string.editsection_activity_title); + Utils.crossFade(captchaContainer, sectionContainer); } public boolean onMenuItemSelected(int featureId, MenuItem item) { @@ -148,6 +215,7 @@ protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); outState.putString("sectionWikitext", sectionWikitext); + outState.putParcelable("captcha", captchaEditResult); } private void fetchSectionText() { @@ -179,4 +247,12 @@ invalidateOptionsMenu(); } + @Override + public void onBackPressed() { + if (captchaEditResult != null) { + cancelCaptcha(); + } else { + finish(); + } + } } \ No newline at end of file diff --git a/wikipedia/src/main/java/org/wikipedia/editing/EditingResult.java b/wikipedia/src/main/java/org/wikipedia/editing/EditingResult.java index 9b623dc..bacd0c2 100644 --- a/wikipedia/src/main/java/org/wikipedia/editing/EditingResult.java +++ b/wikipedia/src/main/java/org/wikipedia/editing/EditingResult.java @@ -1,13 +1,30 @@ package org.wikipedia.editing; -public abstract class EditingResult { +import android.os.Parcel; +import android.os.Parcelable; + +public abstract class EditingResult implements Parcelable { private final String result; public EditingResult(String result) { this.result = result; } + protected EditingResult(Parcel in) { + this.result = in.readString(); + } + public String getResult() { return result; } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(result); + } } diff --git a/wikipedia/src/main/java/org/wikipedia/editing/SuccessEditResult.java b/wikipedia/src/main/java/org/wikipedia/editing/SuccessEditResult.java index 2ae544e..fdaa96e 100644 --- a/wikipedia/src/main/java/org/wikipedia/editing/SuccessEditResult.java +++ b/wikipedia/src/main/java/org/wikipedia/editing/SuccessEditResult.java @@ -1,7 +1,25 @@ package org.wikipedia.editing; +import android.os.Parcel; +import android.os.Parcelable; + public class SuccessEditResult extends EditingResult { public SuccessEditResult() { super("Success"); } + + private SuccessEditResult(Parcel in) { + super(in); + } + + public static final Parcelable.Creator<SuccessEditResult> CREATOR + = new Parcelable.Creator<SuccessEditResult>() { + public SuccessEditResult createFromParcel(Parcel in) { + return new SuccessEditResult(in); + } + + public SuccessEditResult[] newArray(int size) { + return new SuccessEditResult[size]; + } + }; } -- To view, visit https://gerrit.wikimedia.org/r/109597 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Iadce6af2f1dc66bcf41adc19363ca4d28ce56971 Gerrit-PatchSet: 2 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Yuvipanda <yuvipa...@gmail.com> Gerrit-Reviewer: Brion VIBBER <br...@wikimedia.org> Gerrit-Reviewer: Yuvipanda <yuvipa...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits