mirror of https://github.com/kurisufriend/Clover
parent
20c9623851
commit
ee7dffae7d
@ -1,45 +0,0 @@ |
|||||||
<!DOCTYPE html> |
|
||||||
<html> |
|
||||||
<head> |
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1"> |
|
||||||
<style type="text/css"> |
|
||||||
#container { |
|
||||||
width: 440px; |
|
||||||
margin: 0 auto; |
|
||||||
} |
|
||||||
|
|
||||||
#captcha-submit { |
|
||||||
width: 100%; |
|
||||||
height: 30px; |
|
||||||
margin: 10px 0 0 0; |
|
||||||
} |
|
||||||
</style> |
|
||||||
</head> |
|
||||||
<body> |
|
||||||
<div id="container"> |
|
||||||
<div id="captcha-container"></div> |
|
||||||
<input type="button" id="captcha-submit" value="Submit"> |
|
||||||
</div> |
|
||||||
|
|
||||||
<script src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script> |
|
||||||
<script type="text/javascript"> |
|
||||||
(function() { |
|
||||||
|
|
||||||
var container = document.querySelector('#captcha-container'); |
|
||||||
var submitButton = document.querySelector('#captcha-submit') |
|
||||||
|
|
||||||
submitButton.addEventListener('click', function() { |
|
||||||
var challenge = document.querySelector('#recaptcha_challenge_field').value; |
|
||||||
var response = document.querySelector('#recaptcha_response_field').value; |
|
||||||
|
|
||||||
CaptchaCallback.onCaptchaEnteredv1(challenge, response); |
|
||||||
}); |
|
||||||
|
|
||||||
Recaptcha.create('__site_key__', container, { |
|
||||||
theme: 'clean' |
|
||||||
}); |
|
||||||
|
|
||||||
})(); |
|
||||||
</script> |
|
||||||
</body> |
|
||||||
</html> |
|
@ -0,0 +1,40 @@ |
|||||||
|
<div id="captcha-container"> |
||||||
|
<div id="recaptcha_image"></div> |
||||||
|
<input type="hidden" id="recaptcha_response_field" name="recaptcha_response_field"> |
||||||
|
</div> |
||||||
|
|
||||||
|
<script type="text/javascript" |
||||||
|
src="https://www.google.com/recaptcha/api/js/recaptcha_ajax.js"></script> |
||||||
|
<script type="text/javascript"> |
||||||
|
(function() { |
||||||
|
|
||||||
|
Recaptcha.create('__site_key__', 'captcha-container', { |
||||||
|
'theme': 'custom' |
||||||
|
}); |
||||||
|
|
||||||
|
function checkLoaded() { |
||||||
|
var imageSource = null; |
||||||
|
var challengeKey = null; |
||||||
|
|
||||||
|
var image = document.querySelector('#recaptcha_challenge_image'); |
||||||
|
if (image) { |
||||||
|
imageSource = image.getAttribute('src'); |
||||||
|
} |
||||||
|
|
||||||
|
var challenge = document.querySelector('#recaptcha_challenge_field'); |
||||||
|
if (challenge) { |
||||||
|
challengeKey = challenge.getAttribute('value'); |
||||||
|
} |
||||||
|
|
||||||
|
if (imageSource != null && challengeKey != null) { |
||||||
|
CaptchaCallback.onCaptchaLoaded(imageSource, challengeKey); |
||||||
|
} else { |
||||||
|
setTimeout(checkLoaded, 100); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
checkLoaded(); |
||||||
|
|
||||||
|
})(); |
||||||
|
|
||||||
|
</script> |
@ -0,0 +1,7 @@ |
|||||||
|
package org.floens.chan.ui.layout; |
||||||
|
|
||||||
|
public interface CaptchaCallback { |
||||||
|
void captchaLoaded(CaptchaLayoutInterface captchaLayout); |
||||||
|
|
||||||
|
void captchaEntered(CaptchaLayoutInterface captchaLayout, String challenge, String response); |
||||||
|
} |
@ -0,0 +1,7 @@ |
|||||||
|
package org.floens.chan.ui.layout; |
||||||
|
|
||||||
|
public interface CaptchaLayoutInterface { |
||||||
|
void initCaptcha(String baseUrl, String siteKey, boolean lightTheme, CaptchaCallback callback); |
||||||
|
|
||||||
|
void reset(); |
||||||
|
} |
@ -0,0 +1,133 @@ |
|||||||
|
package org.floens.chan.ui.layout; |
||||||
|
|
||||||
|
import android.annotation.SuppressLint; |
||||||
|
import android.content.Context; |
||||||
|
import android.os.Build; |
||||||
|
import android.util.AttributeSet; |
||||||
|
import android.view.View; |
||||||
|
import android.webkit.JavascriptInterface; |
||||||
|
import android.webkit.WebChromeClient; |
||||||
|
import android.webkit.WebSettings; |
||||||
|
import android.webkit.WebView; |
||||||
|
import android.webkit.WebViewClient; |
||||||
|
import android.widget.EditText; |
||||||
|
import android.widget.ImageView; |
||||||
|
import android.widget.LinearLayout; |
||||||
|
|
||||||
|
import org.floens.chan.ChanBuild; |
||||||
|
import org.floens.chan.R; |
||||||
|
import org.floens.chan.ui.view.FixedRatioThumbnailView; |
||||||
|
import org.floens.chan.utils.AndroidUtils; |
||||||
|
import org.floens.chan.utils.IOUtils; |
||||||
|
|
||||||
|
import static org.floens.chan.ui.theme.ThemeHelper.theme; |
||||||
|
import static org.floens.chan.utils.AndroidUtils.setRoundItemBackground; |
||||||
|
|
||||||
|
public class LegacyCaptchaLayout extends LinearLayout implements CaptchaLayoutInterface, View.OnClickListener { |
||||||
|
private FixedRatioThumbnailView image; |
||||||
|
private EditText input; |
||||||
|
private ImageView submit; |
||||||
|
|
||||||
|
private WebView internalWebView; |
||||||
|
|
||||||
|
private String baseUrl; |
||||||
|
private String siteKey; |
||||||
|
private CaptchaCallback callback; |
||||||
|
|
||||||
|
private String challenge; |
||||||
|
|
||||||
|
|
||||||
|
public LegacyCaptchaLayout(Context context) { |
||||||
|
super(context); |
||||||
|
} |
||||||
|
|
||||||
|
public LegacyCaptchaLayout(Context context, AttributeSet attrs) { |
||||||
|
super(context, attrs); |
||||||
|
} |
||||||
|
|
||||||
|
public LegacyCaptchaLayout(Context context, AttributeSet attrs, int defStyleAttr) { |
||||||
|
super(context, attrs, defStyleAttr); |
||||||
|
} |
||||||
|
|
||||||
|
@SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) |
||||||
|
@Override |
||||||
|
protected void onFinishInflate() { |
||||||
|
super.onFinishInflate(); |
||||||
|
|
||||||
|
image = (FixedRatioThumbnailView) findViewById(R.id.image); |
||||||
|
image.setRatio(300f / 57f); |
||||||
|
image.setOnClickListener(this); |
||||||
|
input = (EditText) findViewById(R.id.input); |
||||||
|
submit = (ImageView) findViewById(R.id.submit); |
||||||
|
theme().sendDrawable.apply(submit); |
||||||
|
setRoundItemBackground(submit); |
||||||
|
submit.setOnClickListener(this); |
||||||
|
|
||||||
|
// This captcha layout uses a webview in the background
|
||||||
|
// Because the script changed significantly we can't just load the image straight up from the challenge data anymore.
|
||||||
|
// Now we load a skeleton page in the background, and wait until both the image and challenge key are loaded,
|
||||||
|
// then the onCaptchaLoaded is called through the javascript interface.
|
||||||
|
|
||||||
|
internalWebView = new WebView(getContext()); |
||||||
|
internalWebView.setWebChromeClient(new WebChromeClient()); |
||||||
|
internalWebView.setWebViewClient(new WebViewClient()); |
||||||
|
|
||||||
|
WebSettings settings = internalWebView.getSettings(); |
||||||
|
settings.setJavaScriptEnabled(true); |
||||||
|
|
||||||
|
internalWebView.addJavascriptInterface(new CaptchaInterface(this), "CaptchaCallback"); |
||||||
|
|
||||||
|
//noinspection PointlessBooleanExpression
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && ChanBuild.DEVELOPER_MODE) { |
||||||
|
WebView.setWebContentsDebuggingEnabled(true); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void onClick(View v) { |
||||||
|
if (v == submit) { |
||||||
|
callback.captchaEntered(this, challenge, input.getText().toString()); |
||||||
|
} else if (v == image) { |
||||||
|
reset(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void initCaptcha(String baseUrl, String siteKey, boolean lightTheme, CaptchaCallback callback) { |
||||||
|
this.baseUrl = baseUrl; |
||||||
|
this.siteKey = siteKey; |
||||||
|
this.callback = callback; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void reset() { |
||||||
|
input.setText(""); |
||||||
|
String html = IOUtils.assetAsString(getContext(), "captcha/captcha_legacy.html"); |
||||||
|
html = html.replace("__site_key__", siteKey); |
||||||
|
internalWebView.loadDataWithBaseURL(baseUrl, html, "text/html", "UTF-8", null); |
||||||
|
image.setUrl(null, 0, 0); |
||||||
|
} |
||||||
|
|
||||||
|
private void onCaptchaLoaded(final String imageUrl, final String challenge) { |
||||||
|
this.challenge = challenge; |
||||||
|
image.setUrl(imageUrl, 300, 57); |
||||||
|
} |
||||||
|
|
||||||
|
public static class CaptchaInterface { |
||||||
|
private final LegacyCaptchaLayout layout; |
||||||
|
|
||||||
|
public CaptchaInterface(LegacyCaptchaLayout layout) { |
||||||
|
this.layout = layout; |
||||||
|
} |
||||||
|
|
||||||
|
@JavascriptInterface |
||||||
|
public void onCaptchaLoaded(final String imageUrl, final String challenge) { |
||||||
|
AndroidUtils.runOnUiThread(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
layout.onCaptchaLoaded(imageUrl, challenge); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,36 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<org.floens.chan.ui.layout.LegacyCaptchaLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:orientation="vertical"> |
||||||
|
|
||||||
|
<org.floens.chan.ui.view.FixedRatioThumbnailView |
||||||
|
android:id="@+id/image" |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="80dp" /> |
||||||
|
|
||||||
|
<LinearLayout |
||||||
|
android:layout_width="match_parent" |
||||||
|
android:layout_height="64dp" |
||||||
|
android:orientation="horizontal" |
||||||
|
android:padding="8dp"> |
||||||
|
|
||||||
|
<EditText |
||||||
|
android:id="@+id/input" |
||||||
|
android:layout_width="0dp" |
||||||
|
android:layout_height="match_parent" |
||||||
|
android:layout_weight="1" |
||||||
|
android:hint="@string/reply_captcha_text" |
||||||
|
android:singleLine="true" |
||||||
|
android:textSize="16sp" /> |
||||||
|
|
||||||
|
<ImageView |
||||||
|
android:id="@+id/submit" |
||||||
|
android:layout_width="36dp" |
||||||
|
android:layout_height="36dp" |
||||||
|
android:layout_gravity="center_vertical" |
||||||
|
android:padding="6dp" /> |
||||||
|
|
||||||
|
</LinearLayout> |
||||||
|
|
||||||
|
</org.floens.chan.ui.layout.LegacyCaptchaLayout> |
Loading…
Reference in new issue