diff --git a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParser.java b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParser.java index 19663588..bc22ae89 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParser.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsHtmlParser.java @@ -383,6 +383,15 @@ public class CaptchaNoJsHtmlParser { } return resultImages; + } catch (Throwable error) { + for (Bitmap bitmap : resultImages) { + if (!bitmap.isRecycled()) { + bitmap.recycle(); + } + } + + resultImages.clear(); + throw error; } finally { if (originalBitmap != null) { originalBitmap.recycle(); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java index b9537de8..69fe843e 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsLayoutV2.java @@ -103,6 +103,8 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout captchaVerifyButton.setOnClickListener(this); useOldCaptchaButton.setOnClickListener(this); reloadCaptchaButton.setOnClickListener(this); + + captchaVerifyButton.setEnabled(false); } @Override @@ -153,6 +155,7 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout // called on a background thread AndroidUtils.runOnUiThread(() -> { + captchaVerifyButton.setEnabled(true); renderCaptchaWindow(captchaInfo); }); } @@ -162,6 +165,7 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout // called on a background thread AndroidUtils.runOnUiThread(() -> { + captchaVerifyButton.setEnabled(true); callback.onAuthenticationComplete(this, null, verificationToken); }); } @@ -176,6 +180,7 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout String message = error.getMessage(); showToast(message); + captchaVerifyButton.setEnabled(true); callback.onFallbackToV1CaptchaView(); }); } @@ -224,6 +229,8 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout adapter.setImageSize(imageSize); adapter.setImages(captchaInfo.challengeImages); + + captchaVerifyButton.setEnabled(true); } catch (Throwable error) { if (callback != null) { callback.onFallbackToV1CaptchaView(); @@ -250,10 +257,10 @@ public class CaptchaNoJsLayoutV2 extends FrameLayout List selectedIds = adapter.getCheckedImageIds(); try { - CaptchaNoJsPresenterV2.VerifyError verifyError = presenter.verify(selectedIds); switch (verifyError) { case Ok: + captchaVerifyButton.setEnabled(false); break; case NoImagesSelected: showToast(getContext().getString(R.string.captcha_layout_v2_you_have_to_select_at_least_one_image)); diff --git a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java index 2cfe7392..026b6f79 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsPresenterV2.java @@ -54,10 +54,10 @@ public class CaptchaNoJsPresenterV2 { // this should be updated once in 3 months IIRC private static final String googleCookies = - "SID=NwcOCOnxA7PVDPUY_InSzz6saQ93BmWzg7N2276OPwUvtwXkLpfqbs1tYNkxNP0xC_Awmg.; " + - "HSID=AoZX0-3xQ7lN9EMEm; " + - "SSID=AWwVsHei8i4VlX3H4; " + - "NID=182=ikM1ZwJ0tMSqCiJc8gdretZpOHCnUSsZ2oM7I681KmnkL0DKFOBmFU6zlmTMC_mDnPhBB5mQxsaB0ipTICW9WyCa9nLUbo1Bx-H9jFmOLNhr1E5EezqlyFZcBKEyZgjFYmaY79_5jHMa4uE6v_Vb8HR1Uk9CXbNfw_yIPEsZXZ0t0CURkV-CdxdOIiZ4BAy0oE6w60GJ9kLpOWWSeNZ_lBcn0PkWRj6vmRH6kKrl2exOKnk"; + "SID=gjaHjfFJPAN5HO3MVVZpjHFKa_249dsfjHa9klsiaflsd99.asHqjsM2lAS; " + + "HSID=j7m0aFJ82lPF7Hd9d; " + + "SSID=nJKpa81jOskq7Jsps; " + + "NID=87=gkOAkg09AKnvJosKq82kgnDnHj8Om2pLskKhdna02msog8HkdHDlasDf"; // TODO: inject this in the future when https://github.com/Floens/Clover/pull/678 is merged private final OkHttpClient okHttpClient = new OkHttpClient(); @@ -127,6 +127,7 @@ public class CaptchaNoJsPresenterV2 { public void onFailure(Call call, IOException e) { if (callbacks != null) { try { + prevCaptchaInfo = null; callbacks.onCaptchaInfoParseError(e); } finally { verificationInProgress.set(false); @@ -187,6 +188,7 @@ public class CaptchaNoJsPresenterV2 { public void onFailure(Call call, IOException e) { if (callbacks != null) { try { + prevCaptchaInfo = null; callbacks.onCaptchaInfoParseError(e); } finally { captchaRequestInProgress.set(false); @@ -295,6 +297,10 @@ public class CaptchaNoJsPresenterV2 { if (callbacks != null) { callbacks.onCaptchaInfoParsed(captchaInfo); + } else { + // Return null when callbacks are null to reset prevCaptchaInfo so that we won't + // get stuck without captchaInfo and disabled buttons forever + return null; } return captchaInfo; diff --git a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsV2Adapter.java b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsV2Adapter.java index 72f7c46e..96efb515 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsV2Adapter.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/captcha/v2/CaptchaNoJsV2Adapter.java @@ -58,7 +58,7 @@ public class CaptchaNoJsV2Adapter extends BaseAdapter { convertView = inflater.inflate(R.layout.layout_captcha_challenge_image, parent, false); AppCompatImageView imageView = convertView.findViewById(R.id.captcha_challenge_image); - AppCompatImageView blueCheckmark = convertView.findViewById(R.id.captcha_challenge_blue_checkmark); + ConstraintLayout blueCheckmarkHolder = convertView.findViewById(R.id.captcha_challenge_blue_checkmark_holder); ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(imageSize, imageSize); imageView.setLayoutParams(layoutParams); @@ -68,7 +68,7 @@ public class CaptchaNoJsV2Adapter extends BaseAdapter { boolean isChecked = imageList.get(position).isChecked; AndroidUtils.animateViewScale(imageView, isChecked, ANIMATION_DURATION); - blueCheckmark.setVisibility(isChecked ? View.VISIBLE : View.GONE); + blueCheckmarkHolder.setVisibility(isChecked ? View.VISIBLE : View.GONE); }); if (position >= 0 && position <= imageList.size()) { diff --git a/Clover/app/src/main/java/org/floens/chan/ui/layout/ReplyLayout.java b/Clover/app/src/main/java/org/floens/chan/ui/layout/ReplyLayout.java index 62d9421e..73c53ebf 100644 --- a/Clover/app/src/main/java/org/floens/chan/ui/layout/ReplyLayout.java +++ b/Clover/app/src/main/java/org/floens/chan/ui/layout/ReplyLayout.java @@ -272,22 +272,22 @@ public class ReplyLayout extends LoadView implements View.OnClickListener, Reply break; } case CAPTCHA2_NOJS: - if (!useV2NoJsCaptcha) { - // default webview-based captcha view - authenticationLayout = new CaptchaNojsLayoutV1(getContext()); - } else { + if (useV2NoJsCaptcha) { // new captcha window without webview authenticationLayout = new CaptchaNoJsLayoutV2(getContext()); + } else { + // default webview-based captcha view + authenticationLayout = new CaptchaNojsLayoutV1(getContext()); } ImageView resetButton = captchaContainer.findViewById(R.id.reset); if (resetButton != null) { - if (!useV2NoJsCaptcha) { - // restore the button's visibility when using old v1 captcha view - resetButton.setVisibility(View.VISIBLE); - } else { + if (useV2NoJsCaptcha) { // we don't need the default reset button because we have our own resetButton.setVisibility(View.GONE); + } else { + // restore the button's visibility when using old v1 captcha view + resetButton.setVisibility(View.VISIBLE); } } diff --git a/Clover/app/src/main/res/layout/layout_captcha_challenge_image.xml b/Clover/app/src/main/res/layout/layout_captcha_challenge_image.xml index 855b01bd..de13d603 100644 --- a/Clover/app/src/main/res/layout/layout_captcha_challenge_image.xml +++ b/Clover/app/src/main/res/layout/layout_captcha_challenge_image.xml @@ -14,16 +14,37 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> - + app:layout_constraintTop_toTopOf="@+id/captcha_challenge_image"> + + + + + + + \ No newline at end of file diff --git a/Clover/app/src/main/res/values/strings.xml b/Clover/app/src/main/res/values/strings.xml index 95d6505c..ed7e8ba4 100644 --- a/Clover/app/src/main/res/values/strings.xml +++ b/Clover/app/src/main/res/values/strings.xml @@ -580,7 +580,7 @@ Don't have a 4chan Pass?
Verify Reload Use old captcha - You have to selected at least one image (if you see a captcha that does not have any matching images then it is probably a bug fill an issue and use old captcha for a while) + You have to select at least one image (if you see a captcha that does not have any matching images then it is probably a bug fill an issue and use old captcha for a while) Verification is already in progress Captcha request is already in progress You are requesting captcha too fast