This commit is contained in:
世界 2020-06-26 03:10:18 +00:00
parent 603f6dc0e9
commit 77b6fe7eff
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
19 changed files with 14 additions and 875 deletions

View File

@ -16,9 +16,9 @@ import android.content.pm.PackageManager;
@SuppressWarnings("ConstantConditions")
public class BuildVars {
public static boolean DEBUG_VERSION = false;
public static boolean DEBUG_PRIVATE_VERSION = false;
public static boolean LOGS_ENABLED = false;
public static boolean DEBUG_VERSION = BuildConfig.BUILD_TYPE.equals("debug");
public static boolean DEBUG_PRIVATE_VERSION = DEBUG_VERSION;
public static boolean LOGS_ENABLED;
public static boolean USE_CLOUD_STRINGS = true;
public static int BUILD_VERSION;
@ -46,7 +46,7 @@ public class BuildVars {
if (ApplicationLoader.applicationContext != null) {
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("systemConfig", Context.MODE_PRIVATE);
LOGS_ENABLED = sharedPreferences.getBoolean("logsEnabled", DEBUG_VERSION);
LOGS_ENABLED = sharedPreferences.getBoolean("logsEnabled", LOGS_ENABLED);
}
}
}

View File

@ -47,9 +47,6 @@ public class FileLog {
}
public static void e(final Throwable e) {
if (!BuildVars.LOGS_ENABLED) {
return;
}
Log.e(mkTag(),mkMessage(e),e);
}

View File

@ -526,11 +526,11 @@ public class SettingsActivity extends BaseFragment implements NotificationCenter
AlertUtil.showToast(LocaleController.getString("TextCopied", R.string.TextCopied));
return Unit.INSTANCE;
});
builder.addItem(BuildVars.DEBUG_VERSION ? LocaleController.getString("DebugMenuDisableLogs", R.string.DebugMenuDisableLogs) : LocaleController.getString("DebugMenuEnableLogs", R.string.DebugMenuEnableLogs), R.drawable.baseline_bug_report_24, (it) -> {
builder.addItem(BuildVars.LOGS_ENABLED ? LocaleController.getString("DebugMenuDisableLogs", R.string.DebugMenuDisableLogs) : LocaleController.getString("DebugMenuEnableLogs", R.string.DebugMenuEnableLogs), R.drawable.baseline_bug_report_24, (it) -> {
builder.dismiss();
BuildVars.DEBUG_VERSION = !BuildVars.DEBUG_VERSION;
BuildVars.LOGS_ENABLED = !BuildVars.LOGS_ENABLED;
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("systemConfig", Context.MODE_PRIVATE);
sharedPreferences.edit().putBoolean("logsEnabled", BuildVars.DEBUG_VERSION).apply();
sharedPreferences.edit().putBoolean("logsEnabled", BuildVars.LOGS_ENABLED).apply();
updateRows();
return Unit.INSTANCE;
});

View File

@ -204,8 +204,8 @@ public class NekoConfig {
askBeforeCall = preferences.getBoolean("askBeforeCall", false);
disableNumberRounding = preferences.getBoolean("disableNumberRounding", false);
hideProxyByDefault = preferences.getBoolean("hide_proxy_by_default", BuildVars.isMini);
useProxyItem = preferences.getBoolean("use_proxy_item",false);
hideProxyByDefault = preferences.getBoolean("hide_proxy_by_default", false);
useProxyItem = preferences.getBoolean("use_proxy_item", true);
disableAppBarShadow = preferences.getBoolean("disableAppBarShadow", false);
mediaPreview = preferences.getBoolean("mediaPreview", false);

View File

@ -1,4 +1,4 @@
package tw.nekomimi.nekogram.utils
package tw.nekomimi.nekogram
import android.annotation.SuppressLint
import android.view.View

View File

@ -8,9 +8,7 @@
package tw.nekomimi.nekogram;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
@ -22,24 +20,16 @@ import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import com.github.shadowsocks.plugin.PluginConfiguration;
import com.github.shadowsocks.plugin.PluginContract;
import com.github.shadowsocks.plugin.PluginList;
import com.github.shadowsocks.plugin.PluginManager;
import com.github.shadowsocks.plugin.PluginOptions;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.Utilities;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.BaseFragment;
@ -47,16 +37,12 @@ import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.TextCheckCell;
import org.telegram.ui.Cells.TextInfoPrivacyCell;
import org.telegram.ui.Cells.TextSettingsCell;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.LayoutHelper;
import java.util.ArrayList;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import tw.nekomimi.nekogram.utils.AlertUtil;
import tw.nekomimi.nekogram.utils.PopupBuilder;
public class RelayBatonSettingsActivity extends BaseFragment {

View File

@ -45,7 +45,6 @@ import java.util.ArrayList;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import tw.nekomimi.nekogram.utils.PopupBuilder;
public class ShadowsocksRSettingsActivity extends BaseFragment {

View File

@ -57,7 +57,6 @@ import java.util.ArrayList;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import tw.nekomimi.nekogram.utils.AlertUtil;
import tw.nekomimi.nekogram.utils.PopupBuilder;
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class ShadowsocksSettingsActivity extends BaseFragment {

View File

@ -49,7 +49,6 @@ import java.util.ArrayList;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import tw.nekomimi.nekogram.utils.PopupBuilder;
public class VmessSettingsActivity extends BaseFragment {

View File

@ -28,7 +28,6 @@ import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.EmptyCell;
import org.telegram.ui.Cells.HeaderCell;
import org.telegram.ui.Cells.NotificationsCheckCell;
import org.telegram.ui.Cells.RadioColorCell;
import org.telegram.ui.Cells.ShadowSectionCell;
import org.telegram.ui.Cells.TextCheckCell;
import org.telegram.ui.Cells.TextDetailSettingsCell;
@ -43,7 +42,7 @@ import java.util.ArrayList;
import kotlin.Unit;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.NekoXConfig;
import tw.nekomimi.nekogram.utils.PopupBuilder;
import tw.nekomimi.nekogram.PopupBuilder;
@SuppressLint("RtlHardcoded")
public class NekoChatSettingsActivity extends BaseFragment {

View File

@ -51,7 +51,7 @@ import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.transtale.Translator;
import tw.nekomimi.nekogram.transtale.TranslatorKt;
import tw.nekomimi.nekogram.utils.EnvUtil;
import tw.nekomimi.nekogram.utils.PopupBuilder;
import tw.nekomimi.nekogram.PopupBuilder;
@SuppressLint("RtlHardcoded")
public class NekoGeneralSettingsActivity extends BaseFragment {

View File

@ -1,151 +0,0 @@
package tw.nekomimi.nekogram.translator;
import android.text.TextUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONTokener;
import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import tw.nekomimi.nekogram.NekoConfig;
public class GoogleWebTranslator extends Translator {
private static GoogleWebTranslator instance;
private List<String> targetLanguages = Arrays.asList(
"sq", "ar", "am", "az", "ga", "et", "eu", "be", "bg", "is", "pl", "bs", "fa",
"af", "da", "de", "ru", "fr", "tl", "fi", "fy", "km", "ka", "gu", "kk", "ht",
"ko", "ha", "nl", "ky", "gl", "ca", "cs", "kn", "co", "hr", "ku", "la", "lv",
"lo", "lt", "lb", "ro", "mg", "mt", "mr", "ml", "ms", "mk", "mi", "mn", "bn",
"my", "hmn", "xh", "zu", "ne", "no", "pa", "pt", "ps", "ny", "ja", "sv", "sm",
"sr", "st", "si", "eo", "sk", "sl", "sw", "gd", "ceb", "so", "tg", "te", "ta",
"th", "tr", "cy", "ur", "uk", "uz", "es", "iw", "el", "haw", "sd", "hu", "sn",
"hy", "ig", "it", "yi", "hi", "su", "id", "jw", "en", "yo", "vi", "zh-TW", "zh-CN", "zh");
private long[] tkk;
static GoogleWebTranslator getInstance() {
if (instance == null) {
synchronized (GoogleWebTranslator.class) {
if (instance == null) {
instance = new GoogleWebTranslator();
}
}
}
return instance;
}
@Override
protected String translate(String query, String tl) throws IOException {
String result = translateImpl(query, tl);
if (result == null) {
tkk = null;
return translateImpl(query, tl);
}
return result;
}
@Override
protected List<String> getTargetLanguages() {
return targetLanguages;
}
private String translateImpl(String query, String tl) throws IOException {
if (tkk == null) {
initTkk();
}
if (tkk == null) {
return null;
}
String tk = Utils.signWeb(query, tkk[0], tkk[1]);
String url = "https://translate.google." + (NekoConfig.translationProvider == PROVIDER_GOOGLE_CN ? "cn" : "com") + "/translate_a/single?client=webapp&dt=t&sl=auto" +
"&tl=" + tl +
"&tk=" + tk +
"&q=" + Utils.encodeURIComponent(query); // 不能用URLEncoder
String response = request(url);
if (TextUtils.isEmpty(response)) {
return null;
}
try {
return getResult(response);
} catch (JSONException e) {
FileLog.e(response + e);
return null;
}
}
private String getResult(String string) throws JSONException {
StringBuilder sb = new StringBuilder();
JSONArray array = new JSONArray(new JSONTokener(string)).getJSONArray(0);
for (int i = 0; i < array.length(); i++) {
sb.append(array.getJSONArray(i).getString(0));
}
return sb.toString();
}
private void initTkk() throws IOException {
String response = request("https://translate.google." + (NekoConfig.translationProvider == PROVIDER_GOOGLE_CN ? "cn" : "com"));
if (TextUtils.isEmpty(response)) {
FileLog.e("Tkk init failed");
return;
}
tkk = matchTKK(response);
if (tkk == null) {
FileLog.e("Tkk init failed");
}
}
private long[] matchTKK(String src) {
Matcher matcher = Pattern.compile("tkk\\s*[:=]\\s*['\"]([0-9]+)\\.([0-9]+)['\"]",
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE).matcher(src);
if (matcher.find()) {
if (matcher.group(1) == null || matcher.group(2) == null) {
return null;
}
//noinspection ConstantConditions
return new long[]{Long.parseLong(matcher.group(1)), Long.parseLong(matcher.group(2))};
}
return null;
}
private String request(String url) throws IOException {
ByteArrayOutputStream outbuf;
InputStream httpConnectionStream;
URL downloadUrl = new URL(url);
URLConnection httpConnection = downloadUrl.openConnection();
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1");
httpConnection.setConnectTimeout(1000);
httpConnection.setReadTimeout(2000);
httpConnection.connect();
httpConnectionStream = httpConnection.getInputStream();
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
String result = new String(outbuf.toByteArray());
httpConnectionStream.close();
outbuf.close();
return result;
}
}

View File

@ -1,138 +0,0 @@
package tw.nekomimi.nekogram.translator;
import android.text.TextUtils;
import androidx.annotation.Keep;
import com.google.gson.Gson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
public class LingoTranslator extends Translator {
private static LingoTranslator instance;
private List<String> targetLanguages = Arrays.asList("zh", "en", "es", "fr", "ja", "ru");
static LingoTranslator getInstance() {
if (instance == null) {
synchronized (LingoTranslator.class) {
if (instance == null) {
instance = new LingoTranslator();
}
}
}
return instance;
}
@Override
protected List<String> getTargetLanguages() {
return targetLanguages;
}
@Override
protected String translate(String query, String tl) throws IOException {
LingoRequest params = new LingoRequest(query, "auto2" + tl);
Gson gson = new Gson();
String response = request(gson.toJson(params));
if (TextUtils.isEmpty(response)) {
return null;
}
LingoResponse lingoResponse = gson.fromJson(response, LingoResponse.class);
if (TextUtils.isEmpty(lingoResponse.target)) {
FileLog.e(response);
return null;
}
return lingoResponse.target;
}
private String request(String param) throws IOException {
ByteArrayOutputStream outbuf;
InputStream httpConnectionStream;
URL downloadUrl = new URL("https://api.interpreter.caiyunai.com/v1/translator");
HttpURLConnection httpConnection = (HttpURLConnection) downloadUrl.openConnection();
httpConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
httpConnection.addRequestProperty("X-Authorization", "token 9sdftiq37bnv410eon2l");//白嫖
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1");
httpConnection.setConnectTimeout(1000);
httpConnection.setReadTimeout(2000);
httpConnection.setRequestMethod("POST");
httpConnection.setDoOutput(true);
DataOutputStream dataOutputStream = new DataOutputStream(httpConnection.getOutputStream());
//noinspection CharsetObjectCanBeUsed
byte[] t = param.getBytes("UTF-8");
dataOutputStream.write(t);
dataOutputStream.flush();
dataOutputStream.close();
httpConnection.connect();
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
httpConnectionStream = httpConnection.getErrorStream();
} else {
httpConnectionStream = httpConnection.getInputStream();
}
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
String result = new String(outbuf.toByteArray());
httpConnectionStream.close();
outbuf.close();
return result;
}
public static class LingoRequest {
@SerializedName("source")
@Expose
@Keep
public String source;
@SerializedName("trans_type")
@Expose
@Keep
String transType;
@SerializedName("request_id")
@Expose
@Keep
String requestId;
@SerializedName("detect")
@Expose
@Keep
Boolean detect;
LingoRequest(String source, String transType) {
super();
this.source = source;
this.transType = transType;
this.requestId = String.valueOf(System.currentTimeMillis());
this.detect = true;
}
}
static class LingoResponse {
@SerializedName("target")
@Expose
String target;
}
}

View File

@ -1,211 +0,0 @@
package tw.nekomimi.nekogram.translator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.text.TextUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.browser.Browser;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RadialProgressView;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import tw.nekomimi.nekogram.NekoConfig;
public class TranslateBottomSheet extends BottomSheet {
@SuppressLint("StaticFieldLeak")
private static TranslateBottomSheet instance;
private WebView webView;
private RadialProgressView progressBar;
private Activity parentActivity;
private FrameLayout containerLayout;
private String url;
@SuppressLint("SetJavaScriptEnabled")
protected TranslateBottomSheet(Context context, final String text) {
super(context, false);
setApplyTopPadding(false);
setApplyBottomPadding(false);
setCanDismissWithSwipe(false);
if (context instanceof Activity) {
parentActivity = (Activity) context;
}
try {
switch (NekoConfig.translationProvider) {
case Translator.PROVIDER_GOOGLE_WEB:
url = String.format("https://translate.google.com/?view=home&op=translate&text=%s", URLEncoder.encode(text, "UTF-8"));
break;
case Translator.PROVIDER_GOOGLE_CN_WEB:
url = String.format("https://translate.google.cn/?view=home&op=translate&text=%s", URLEncoder.encode(text, "UTF-8"));
break;
case Translator.PROVIDER_BAIDU_WEB:
url = String.format("https://fanyi.baidu.com/?aldtype=38319&tpltype=sigma#auto/zh/%s", Utils.encodeURIComponent(text));
break;
case Translator.PROVIDER_DEEPL_WEB:
url = String.format("https://www.deepl.com/translator#auto/auto/%s", Utils.encodeURIComponent(text));
break;
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
containerLayout = new FrameLayout(context) {
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
try {
if ((webView.getVisibility() != VISIBLE) && webView.getParent() != null) {
removeView(webView);
webView.stopLoading();
webView.loadUrl("about:blank");
webView.destroy();
}
} catch (Exception e) {
FileLog.e(e);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int h = (int) (AndroidUtilities.displaySize.y / 1.5);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h + AndroidUtilities.dp(48) + 1, MeasureSpec.EXACTLY));
}
};
containerLayout.setOnTouchListener((v, event) -> true);
setCustomView(containerLayout);
webView = new WebView(context);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
if (Build.VERSION.SDK_INT >= 17) {
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
}
if (Build.VERSION.SDK_INT >= 21) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptThirdPartyCookies(webView, true);
}
webView.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.INVISIBLE);
}
});
containerLayout.addView(webView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 0, 0, 0, 48));
progressBar = new RadialProgressView(context);
progressBar.setVisibility(View.INVISIBLE);
containerLayout.addView(progressBar, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 0, 0, 0, (48) / 2));
View lineView = new View(context);
lineView.setBackgroundColor(Theme.getColor(Theme.key_dialogGrayLine));
containerLayout.addView(lineView, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 1, Gravity.LEFT | Gravity.BOTTOM));
((FrameLayout.LayoutParams) lineView.getLayoutParams()).bottomMargin = AndroidUtilities.dp(48);
FrameLayout frameLayout = new FrameLayout(context);
frameLayout.setBackgroundColor(Theme.getColor(Theme.key_dialogBackground));
containerLayout.addView(frameLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.LEFT | Gravity.BOTTOM));
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
linearLayout.setWeightSum(1);
frameLayout.addView(linearLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.RIGHT));
TextView textView = new TextView(context);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
textView.setTextColor(Theme.getColor(Theme.key_dialogTextBlue4));
textView.setGravity(Gravity.CENTER);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_dialogButtonSelector), 0));
textView.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
textView.setText(LocaleController.getString("Close", R.string.Close).toUpperCase());
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
frameLayout.addView(textView, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
textView.setOnClickListener(v -> dismiss());
TextView openInButton = new TextView(context);
openInButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
openInButton.setTextColor(Theme.getColor(Theme.key_dialogTextBlue4));
openInButton.setGravity(Gravity.CENTER);
openInButton.setSingleLine(true);
openInButton.setEllipsize(TextUtils.TruncateAt.END);
openInButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_dialogButtonSelector), 0));
openInButton.setPadding(AndroidUtilities.dp(18), 0, AndroidUtilities.dp(18), 0);
openInButton.setText(LocaleController.getString("OpenInBrowser", R.string.OpenInBrowser).toUpperCase());
openInButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
linearLayout.addView(openInButton, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
openInButton.setOnClickListener(v -> {
Browser.openUrl(parentActivity, url);
dismiss();
});
setDelegate(new BottomSheet.BottomSheetDelegate() {
@Override
public void onOpenAnimationEnd() {
progressBar.setVisibility(View.VISIBLE);
webView.setVisibility(View.VISIBLE);
try {
webView.loadUrl(url);
} catch (Exception e) {
FileLog.e(e);
}
}
});
instance = this;
}
public static void show(Context context, final String text) {
if (instance != null) {
instance.destroy();
}
new TranslateBottomSheet(context, text).show();
}
public static TranslateBottomSheet getInstance() {
return instance;
}
public void destroy() {
if (webView != null && webView.getVisibility() == View.VISIBLE) {
containerLayout.removeView(webView);
webView.stopLoading();
webView.loadUrl("about:blank");
webView.destroy();
}
instance = null;
dismissInternal();
}
}

View File

@ -1,133 +0,0 @@
package tw.nekomimi.nekogram.translator;
import android.annotation.SuppressLint;
import android.os.AsyncTask;
import org.json.JSONException;
import org.telegram.messenger.LocaleController;
import org.telegram.tgnet.TLRPC;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
import tw.nekomimi.nekogram.NekoConfig;
abstract public class Translator {
public static final int PROVIDER_GOOGLE = 1;
public static final int PROVIDER_GOOGLE_CN = 2;
public static final int PROVIDER_LINGO = 3;
public static final int PROVIDER_YANDEX = 4;
public static final int PROVIDER_GOOGLE_WEB = -1;
public static final int PROVIDER_GOOGLE_CN_WEB = -2;
public static final int PROVIDER_BAIDU_WEB = -3;
public static final int PROVIDER_DEEPL_WEB = -4;
public static void translate(Object query, TranslateCallBack translateCallBack) {
Locale locale = LocaleController.getInstance().currentLocale;
String toLang;
if (NekoConfig.translationProvider != PROVIDER_LINGO && NekoConfig.translationProvider != PROVIDER_YANDEX && locale.getLanguage().equals("zh") && (locale.getCountry().toUpperCase().equals("CN") || locale.getCountry().toUpperCase().equals("TW"))) {
toLang = locale.getLanguage() + "-" + locale.getCountry().toUpperCase();
} else {
toLang = locale.getLanguage();
}
Translator translator;
switch (NekoConfig.translationProvider) {
case PROVIDER_YANDEX:
translator = YandexTranslator.getInstance();
break;
case PROVIDER_GOOGLE:
case PROVIDER_GOOGLE_CN:
translator = GoogleWebTranslator.getInstance();
break;
case PROVIDER_LINGO:
default:
translator = LingoTranslator.getInstance();
break;
}
if (!translator.getTargetLanguages().contains(toLang)) {
translateCallBack.onUnsupported();
} else {
translator.startTask(query, toLang, translateCallBack);
}
}
private void startTask(Object query, String toLang, TranslateCallBack translateCallBack) {
new MyAsyncTask().request(query, toLang, translateCallBack).execute();
}
abstract protected String translate(String query, String tl) throws IOException, JSONException;
abstract protected List<String> getTargetLanguages();
public interface TranslateCallBack {
void onSuccess(Object translation);
void onError(Throwable e);
void onUnsupported();
}
@SuppressLint("StaticFieldLeak")
private class MyAsyncTask extends AsyncTask<Void, Integer, Object> {
TranslateCallBack translateCallBack;
Object query;
String tl;
public MyAsyncTask request(Object query, String tl, TranslateCallBack translateCallBack) {
this.query = query;
this.tl = tl;
this.translateCallBack = translateCallBack;
return this;
}
@Override
protected Object doInBackground(Void... params) {
try {
if (query instanceof String) {
return translate((String) query, tl);
} else if (query instanceof TLRPC.Poll) {
TLRPC.TL_poll poll = new TLRPC.TL_poll();
TLRPC.TL_poll original = (TLRPC.TL_poll) query;
poll.question = original.question +
"\n" +
"--------" +
"\n" + translate(original.question, tl);
for (int i = 0; i < original.answers.size(); i++) {
TLRPC.TL_pollAnswer answer = new TLRPC.TL_pollAnswer();
answer.text = original.answers.get(i).text + " | " + translate(original.answers.get(i).text, tl);
answer.option = original.answers.get(i).option;
poll.answers.add(answer);
}
poll.close_date = original.close_date;
poll.close_period = original.close_period;
poll.closed = original.closed;
poll.flags = original.flags;
poll.id = original.id;
poll.multiple_choice = original.multiple_choice;
poll.public_voters = original.public_voters;
poll.quiz = original.quiz;
return poll;
} else {
throw new UnsupportedOperationException("Unsupported translation query");
}
} catch (Throwable e) {
return e;
}
}
@Override
protected void onPostExecute(Object result) {
if (result == null) {
translateCallBack.onError(null);
} else if (result instanceof Throwable) {
translateCallBack.onError((Throwable) result);
} else {
translateCallBack.onSuccess(result);
}
}
}
}

View File

@ -1,80 +0,0 @@
package tw.nekomimi.nekogram.translator;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
/**
* @author Bin
*/
class Utils {
static String signWeb(String text, long key1, long key2) {
List<Integer> c = new ArrayList<>();
for (int F = 0; F < text.length(); F++) {
int p = text.charAt(F);
if (128 > p) {
c.add(p);
} else {
if (2048 > p) {
c.add(p >> 6 | 192);
} else {
if ((55296 == (64512 & p) && F + 1 < text.length() && 56320 == (64512 & text.charAt(F + 1)))) {
p = 65536 + ((1023 & p) << 10) + (1023 & text.charAt(++F));
c.add(p >> 18 | 240);
c.add(p >> 12 & 63 | 128);
} else {
c.add(p >> 12 | 224);
}
c.add(p >> 6 & 63 | 128);
}
c.add(63 & p | 128);
}
}
String formula1 = "+-a^+6";
String formula2 = "+-3^+b+-f";
long v = key1;
for (Integer i : c) {
v += i;
v = n(v, formula1);
}
v = n(v, formula2);
v ^= key2;
if (0 > v)
v = (0x7fffffff & v) + 0x80000000L;
v %= 1e6;
return v + "." + (v ^ key1);
}
private static long n(long r, String o) {
for (int t = 0; t < o.length() - 2; t += 3) {
long e = o.charAt(t + 2);
e = e >= 'a' ? e - 87 : e - '0';
e = '+' == o.charAt(t + 1) ? r >>> e : r << e;
r = '+' == o.charAt(t) ? r + e & 0xffffffffL : r ^ e;
}
return r;
}
static String encodeURIComponent(String str) {
if (str == null) return null;
byte[] bytes = str.getBytes(Charset.defaultCharset());
StringBuilder builder = new StringBuilder(bytes.length);
for (byte c : bytes) {
String HEX = "0123456789ABCDEF";
if (c >= 'a' ? c <= 'z' || c == '~' :
c >= 'A' ? c <= 'Z' || c == '_' :
c >= '0' ? c <= '9' : c == '-' || c == '.')
builder.append((char) c);
else
builder.append('%')
.append(HEX.charAt(c >> 4 & 0xf))
.append(HEX.charAt(c & 0xf));
}
return builder.toString();
}
}

View File

@ -1,128 +0,0 @@
package tw.nekomimi.nekogram.translator;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.List;
public class YandexTranslator extends Translator {
private static YandexTranslator instance;
private List<String> targetLanguages = Arrays.asList(
"en", "af", "am", "ar", "az", "be", "bg", "bn", "bs", "ca", "ceb", "cs", "cy",
"da", "de", "el", "eo", "es", "et", "eu", "fa", "fi", "fr", "ga", "gd", "gl", "gu",
"he", "hi", "hr", "ht", "hu", "hy", "id", "is", "it", "ja", "jv", "ka", "kk", "km",
"kn", "ko", "ky", "la", "lb", "lo", "lt", "lv", "mg", "mi", "mk", "ml", "mn", "mr",
"ms", "mt", "my", "ne", "nl", "no", "pa", "pl", "pt", "ro", "ru", "si", "sk", "sl",
"sq", "sr", "su", "sv", "sw", "ta", "te", "tg", "th", "tl", "tr", "tt", "uk", "ur",
"uz", "vi", "xh", "yi", "zh");
static YandexTranslator getInstance() {
if (instance == null) {
synchronized (YandexTranslator.class) {
if (instance == null) {
instance = new YandexTranslator();
}
}
}
return instance;
}
private static String getResult(String string) throws JSONException {
JSONObject json = new JSONObject(string);
int code = json.getInt("code");
if (code != 200) {
return null;
}
JSONArray array = json.getJSONArray("text");
StringBuilder sb = new StringBuilder();
int length = array.length();
for (int i = 0; i < length; i++) {
sb.append(array.getString(i));
}
return sb.toString();
}
@Override
protected String translate(String query, String tl) throws IOException, JSONException {
String result = translateImpl(query, tl);
if (result == null) {
return translateImpl(query, tl);
}
return result;
}
@Override
protected List<String> getTargetLanguages() {
return targetLanguages;
}
private String translateImpl(String query, String tl) throws IOException, JSONException {
String url = "https://translate.yandex.net/api/v1.5/tr.json/translate"
+ "?key=trnsl.1.1.20160205T121943Z.0208eaff12c2747d.9526187390798b3098ec23e8f02073168e0b52c1"
+ "&lang=" + tl;
return getResult(request(url, "text=" + URLEncoder.encode(query, "UTF-8")));
}
private String request(String url, String param) throws IOException {
ByteArrayOutputStream outbuf;
InputStream httpConnectionStream;
URL downloadUrl = new URL(url);
HttpURLConnection httpConnection = (HttpURLConnection) downloadUrl.openConnection();
httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded charset=UTF-8");
httpConnection.addRequestProperty("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 10_0 like Mac OS X) AppleWebKit/602.1.38 (KHTML, like Gecko) Version/10.0 Mobile/14A5297c Safari/602.1");
httpConnection.setConnectTimeout(1000);
httpConnection.setReadTimeout(2000);
httpConnection.setRequestMethod("POST");
httpConnection.setDoOutput(true);
DataOutputStream dataOutputStream = new DataOutputStream(httpConnection.getOutputStream());
//noinspection CharsetObjectCanBeUsed
byte[] t = param.getBytes("UTF-8");
dataOutputStream.write(t);
dataOutputStream.flush();
dataOutputStream.close();
httpConnection.connect();
if (httpConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
httpConnectionStream = httpConnection.getErrorStream();
} else {
httpConnectionStream = httpConnection.getInputStream();
}
outbuf = new ByteArrayOutputStream();
byte[] data = new byte[1024 * 32];
while (true) {
int read = httpConnectionStream.read(data);
if (read > 0) {
outbuf.write(data, 0, read);
} else if (read == -1) {
break;
} else {
break;
}
}
String result = new String(outbuf.toByteArray());
try {
httpConnectionStream.close();
} catch (Throwable e) {
FileLog.e(e);
}
try {
outbuf.close();
} catch (Exception ignore) {
}
return result;
}
}

View File

@ -10,7 +10,7 @@ import tw.nekomimi.nekogram.NekoConfig
import tw.nekomimi.nekogram.transtale.source.GoogleWebTranslator
import tw.nekomimi.nekogram.transtale.source.LingoTranslator
import tw.nekomimi.nekogram.transtale.source.YandexTranslator
import tw.nekomimi.nekogram.utils.PopupBuilder
import tw.nekomimi.nekogram.PopupBuilder
import tw.nekomimi.nekogram.utils.UIUtil
import tw.nekomimi.nekogram.utils.receive
import tw.nekomimi.nekogram.utils.receiveLazy

View File

@ -13,6 +13,7 @@ import org.telegram.ui.Components.EditTextBoldCursor
import org.telegram.ui.Components.NumberPicker
import tw.nekomimi.nekogram.BottomBuilder
import tw.nekomimi.nekogram.NekoConfig
import tw.nekomimi.nekogram.PopupBuilder
import java.util.*
import java.util.concurrent.atomic.AtomicReference