This commit is contained in:
世界 2020-05-01 10:01:23 +08:00
parent c775d4f0e8
commit a64472561f
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
12 changed files with 359 additions and 254 deletions

View File

@ -65,7 +65,7 @@ android {
minSdkVersion 16
targetSdkVersion 28
versionName "6.1.0.2-rc01"
versionName "6.1.1.0-rc01"
versionCode = 27
vectorDrawables.generatedDensities = ['mdpi', 'hdpi', 'xhdpi', 'xxhdpi']

View File

@ -107,6 +107,7 @@ import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
@ -186,20 +187,15 @@ import java.io.File;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import cn.hutool.core.util.StrUtil;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.parts.ArticleTransKt;
import tw.nekomimi.nekogram.transtale.TranslateDb;
import tw.nekomimi.nekogram.transtale.Translator;
import tw.nekomimi.nekogram.utils.AlertUtil;
import tw.nekomimi.nekogram.utils.UIUtil;
import static org.telegram.messenger.MessageObject.POSITION_FLAG_BOTTOM;
import static org.telegram.messenger.MessageObject.POSITION_FLAG_LEFT;
@ -208,7 +204,7 @@ import static org.telegram.messenger.MessageObject.POSITION_FLAG_TOP;
public class ArticleViewer implements NotificationCenter.NotificationCenterDelegate, GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
private Activity parentActivity;
public Activity parentActivity;
private BaseFragment parentFragment;
private ArrayList<BlockEmbedCell> createdWebViews = new ArrayList<>();
@ -276,7 +272,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
private RecyclerListView[] listView;
private LinearLayoutManager[] layoutManager;
private WebpageAdapter[] adapter;
public WebpageAdapter[] adapter;
private AnimatorSet pageSwitchAnimation;
@ -320,7 +316,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
private static final int open_item = 4;
private static final int settings_item = 5;
private ActionBarMenuSubItem transMenu;
public ActionBarMenuSubItem transMenu;
private int anchorsOffsetMeasuredWidth;
@ -1975,7 +1971,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}
private CharSequence getText(WebpageAdapter adapter, View parentView, TLRPC.RichText parentRichText, TLRPC.RichText richText, TLRPC.PageBlock parentBlock, int maxWidth, boolean noTranslate) {
public CharSequence getText(WebpageAdapter adapter, View parentView, TLRPC.RichText parentRichText, TLRPC.RichText richText, TLRPC.PageBlock parentBlock, int maxWidth, boolean noTranslate) {
if (richText == null) {
return null;
}
@ -2918,7 +2914,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}
}
private void updatePaintSize() {
public void updatePaintSize() {
for (int i = 0; i < 2; i++) {
adapter[i].notifyDataSetChanged();
}
@ -3656,7 +3652,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
if (!adapter[0].trans) {
adapter[0].trans = true;
transMenu.setTextAndIcon(LocaleController.getString("UndoTranslate", R.string.UndoTranslate), R.drawable.photo_undo);
doTransLATE();
ArticleTransKt.doTransLATE(this);
} else {
adapter[0].trans = false;
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate);
@ -4067,170 +4063,6 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
updatePaintColors();
}
private void doTransLATE() {
AlertDialog.Builder proc = new AlertDialog.Builder(parentActivity, 3);
ExecutorService transPool = Executors.newFixedThreadPool(5);
AtomicBoolean cancel = new AtomicBoolean(false);
proc.setOnCancelListener((it) -> {
adapter[0].trans = false;
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate);
cancel.set(true);
transPool.shutdown();
});
AlertDialog dialog = proc.show();
UIUtil.runOnIoDispatcher(() -> {
HashMap<Object, TLRPC.PageBlock> copy = new HashMap<>(adapter[0].textToBlocks);
ArrayList<Object> array = new ArrayList<>(adapter[0].textBlocks);
AtomicInteger errorCount = new AtomicInteger();
AtomicInteger taskCount = new AtomicInteger(array.size());
for (Object item : array) {
if (item instanceof TLRPC.TL_textConcat) {
taskCount.addAndGet(((TLRPC.TL_textConcat) item).texts.size() - 1);
}
}
try {
for (int b = 0, N = array.size(); b < N; b++) {
Object object = array.get(b);
TLRPC.PageBlock block = copy.get(object);
String textToSearchIn = null;
if (object instanceof TLRPC.RichText) {
TLRPC.RichText richText = (TLRPC.RichText) object;
if (richText.texts.size() > 0) {
for (TLRPC.RichText node : richText.texts) {
String nodeText = getText(adapter[0], null, node, node, block, 1000).toString();
if (TranslateDb.contains(nodeText)) {
taskCount.decrementAndGet();
continue;
}
transPool.execute(() -> {
if (cancel.get()) return;
String localeText;
try {
localeText = Translator.translate(nodeText);
if (cancel.get()) return;
} catch (Exception e) {
if (cancel.get()) return;
boolean finaL = taskCount.decrementAndGet() == 0;
if (errorCount.incrementAndGet() > 3 || finaL) {
UIUtil.runOnUIThread(() -> {
dialog.dismiss();
adapter[0].trans = false;
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate);
});
AlertUtil.showSimpleAlert(parentActivity, e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage());
cancel.set(true);
transPool.shutdown();
AlertUtil.showTransFailedDialog(parentActivity, e instanceof UnsupportedOperationException, e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage(), this::doTransLATE);
}
return;
}
TranslateDb.save(nodeText, localeText);
UIUtil.runOnUIThread(this::updatePaintSize);
boolean finaL = taskCount.decrementAndGet() < 1;
if (finaL) {
UIUtil.runOnUIThread(dialog::dismiss);
transPool.shutdown();
}
});
}
return;
}
CharSequence innerText = getText(adapter[0], null, richText, richText, block, 1000);
if (!TextUtils.isEmpty(innerText)) {
textToSearchIn = innerText.toString();
}
} else if (object instanceof String) {
textToSearchIn = ((String) object);
}
if (textToSearchIn != null) {
if (TranslateDb.contains(textToSearchIn)) {
taskCount.decrementAndGet();
continue;
}
String finalTextToSearchIn = textToSearchIn;
transPool.execute(() -> {
if (cancel.get()) return;
String localeText;
try {
localeText = Translator.translate(finalTextToSearchIn);
if (cancel.get()) return;
} catch (Exception e) {
if (cancel.get()) return;
boolean finaL = taskCount.decrementAndGet() == 0;
if (errorCount.incrementAndGet() > 3 || finaL) {
UIUtil.runOnUIThread(() -> {
dialog.dismiss();
adapter[0].trans = false;
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate);
});
AlertUtil.showSimpleAlert(parentActivity, e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage());
cancel.set(true);
transPool.shutdown();
AlertUtil.showTransFailedDialog(parentActivity, e instanceof UnsupportedOperationException, e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage(), this::doTransLATE);
}
return;
}
TranslateDb.save(finalTextToSearchIn, localeText);
UIUtil.runOnUIThread(this::updatePaintSize);
boolean finaL = taskCount.decrementAndGet() < 1;
if (finaL) {
UIUtil.runOnUIThread(dialog::dismiss);
transPool.shutdown();
}
});
}
}
if (taskCount.get() == 0) {
transPool.shutdown();
UIUtil.runOnUIThread(dialog::dismiss);
UIUtil.runOnUIThread(this::updatePaintSize);
}
} catch (Exception ignored) {
transPool.shutdown();
UIUtil.runOnUIThread(dialog::dismiss);
UIUtil.runOnUIThread(this::updatePaintSize);
}
});
}
private void showSearch(boolean show) {
if (searchContainer == null || (searchContainer.getTag() != null) == show) {
return;
@ -5308,7 +5140,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}
}
private class WebpageAdapter extends RecyclerListView.SelectionAdapter {
public class WebpageAdapter extends RecyclerListView.SelectionAdapter {
private Context context;
private ArrayList<TLRPC.PageBlock> localBlocks = new ArrayList<>();
@ -5319,8 +5151,8 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
private HashMap<String, TLRPC.TL_textAnchor> anchorsParent = new HashMap<>();
private HashMap<TLRPC.TL_pageBlockAudio, MessageObject> audioBlocks = new HashMap<>();
private ArrayList<MessageObject> audioMessages = new ArrayList<>();
private HashMap<Object, TLRPC.PageBlock> textToBlocks = new HashMap<>();
private ArrayList<Object> textBlocks = new ArrayList<>();
public HashMap<Object, TLRPC.PageBlock> textToBlocks = new HashMap<>();
public ArrayList<Object> textBlocks = new ArrayList<>();
private HashMap<String, Integer> searchTextOffset = new HashMap<>();
private TLRPC.WebPage currentPage;
@ -6339,6 +6171,8 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
}
private void cleanup() {
trans = false;
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate);
currentPage = null;
blocks.clear();
photoBlocks.clear();

View File

@ -3,6 +3,7 @@ package org.telegram.ui.Cells;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
@ -34,6 +35,7 @@ import android.widget.TextView;
import androidx.recyclerview.widget.LinearLayoutManager;
import org.jetbrains.annotations.NotNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.Emoji;
@ -41,6 +43,7 @@ import org.telegram.messenger.MessageObject;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.FloatingActionMode;
import org.telegram.ui.ActionBar.FloatingToolbar;
import org.telegram.ui.ActionBar.Theme;
@ -50,6 +53,11 @@ import org.telegram.ui.Components.RecyclerListView;
import java.util.ArrayList;
import tw.nekomimi.nekogram.transtale.TranslateDb;
import tw.nekomimi.nekogram.transtale.Translator;
import tw.nekomimi.nekogram.utils.AlertUtil;
import tw.nekomimi.nekogram.utils.ProxyUtil;
import static org.telegram.ui.ActionBar.FloatingToolbar.STYLE_THEME;
import static org.telegram.ui.ActionBar.Theme.key_chat_inTextSelectionHighlight;
@ -1216,8 +1224,9 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
final ActionMode.Callback callback = new ActionMode.Callback() {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.add(Menu.NONE, android.R.id.copy, 0, android.R.string.copy);
menu.add(Menu.NONE, android.R.id.selectAll, 1, android.R.string.selectAll);
menu.add(Menu.NONE, 0, 0, android.R.string.copy);
menu.add(Menu.NONE, 1, 1, android.R.string.selectAll);
menu.add(Menu.NONE, 2, 2, R.string.Translate);
return true;
}
@ -1230,6 +1239,7 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
} else {
menu.getItem(1).setVisible(true);
}
menu.getItem(2).setVisible(selectedView instanceof View);
}
return true;
}
@ -1240,10 +1250,10 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
return true;
}
switch (item.getItemId()) {
case android.R.id.copy:
case 0:
copyText();
return true;
case android.R.id.selectAll:
case 1: {
CharSequence text = getText(selectedView, false);
if (text == null) {
return true;
@ -1254,6 +1264,35 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
invalidate();
showActions();
return true;
}
case 2:
CharSequence textS = getTextForCopy();
if (textS == null) {
return true;
}
String urlFinal = textS.toString();
Activity activity = ProxyUtil.getOwnerActivity((((View) selectedView).getContext()));
if (TranslateDb.contains(urlFinal)) {
AlertUtil.showSimpleAlert(activity, TranslateDb.query(urlFinal));
} else {
AlertDialog pro = AlertUtil.showProgress(activity);
pro.show();
Translator.translate(urlFinal, new Translator.Companion.TranslateCallBack() {
@Override public void onSuccess(@NotNull String translation) {
TranslateDb.save(urlFinal, translation);
pro.dismiss();
AlertUtil.showSimpleAlert(activity, translation);
}
@Override public void onFailed(boolean unsupported, @NotNull String message) {
pro.dismiss();
AlertUtil.showTransFailedDialog(activity, unsupported, message, () -> {
pro.show();
Translator.translate(urlFinal, this);
});
}
});
}
default:
clear();
}
@ -1429,8 +1468,15 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
public static class Callback {
public void onStateChanged(boolean isSelected){};
public void onTextCopied(){};
public void onStateChanged(boolean isSelected) {
}
;
public void onTextCopied() {
}
;
}
protected void fillLayoutForOffset(int offset, LayoutBlock layoutBlock) {

View File

@ -14303,11 +14303,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
message.isFromUser());
boolean allowViewHistory = currentUser == null
&& (currentChat != null && !currentChat.broadcast && message.isFromUser());
if (allowPrpr && NekoConfig.showPrPr) {
items.add(LocaleController.getString("Prpr", R.string.Prpr));
options.add(92);
icons.add(R.drawable.msg_prpr);
}
if (allowViewHistory && NekoConfig.showViewHistory) {
items.add(LocaleController.getString("ViewUserHistory", R.string.ViewHistory));
options.add(90);
@ -15475,30 +15471,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
showMessagesSearchListView(true);
break;
}
case 92: {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(selectedObject.messageOwner.from_id);
if (user.username != null) {
SendMessagesHelper.getInstance(currentAccount).sendMessage("/prpr@" + user.username, dialog_id, selectedObject, null, false,
null, null, null, true, 0);
} else {
SpannableString spannableString = new SpannableString("/prpr@" + user.first_name);
spannableString.setSpan(new URLSpanUserMention(Integer.toString(user.id), 1), 6, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
CharSequence[] cs = new CharSequence[]{spannableString};
boolean supportsSendingNewEntities = true;
long peer = getDialogId();
if ((int) peer == 0) {
int high_id = (int) (peer >> 32);
TLRPC.EncryptedChat encryptedChat = getMessagesController().getEncryptedChat(high_id);
if (encryptedChat == null || AndroidUtilities.getPeerLayerVersion(encryptedChat.layer) < 101) {
supportsSendingNewEntities = false;
}
}
ArrayList<TLRPC.MessageEntity> entities = getMediaDataController().getEntities(cs, supportsSendingNewEntities);
SendMessagesHelper.getInstance(currentAccount).sendMessage(spannableString.toString(), dialog_id, selectedObject, null, false,
entities, null, null, true, 0);
}
break;
}
case 91: {
if (Build.VERSION.SDK_INT >= 23 && getParentActivity().checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
getParentActivity().requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 4);

View File

@ -351,7 +351,7 @@ public class LoginActivity extends BaseFragment implements NotificationCenter.No
MessagesController.getInstance(currentAccount).putUser(res.user, false);
ContactsController.getInstance(currentAccount).checkAppAccount();
MessagesController.getInstance(currentAccount).getBlockedUsers(true);
MessagesController.getInstance(currentAccount).checkProxyInfo(true);
MessagesController.getInstance(currentAccount).checkPromoInfo(true);
ConnectionsManager.getInstance(currentAccount).updateDcSettings();
needFinishActivity(false);
} else {

View File

@ -35,7 +35,6 @@ public class NekoConfig {
public static boolean showAddToSavedMessages;
public static boolean showReport;
public static boolean showPrPr;
public static boolean showViewHistory;
public static boolean showAdminActions;
public static boolean showChangePermissions;
@ -91,6 +90,10 @@ public class NekoConfig {
public static String cachePath;
public static String translateToLang;
public static String translateInputLang = "en";
static {
useIPv6 = preferences.getBoolean("useIPv6", false);
@ -105,7 +108,6 @@ public class NekoConfig {
hideProxySponsorChannel = preferences.getBoolean("hideProxySponsorChannel", false);
showAddToSavedMessages = preferences.getBoolean("showAddToSavedMessages", true);
showReport = preferences.getBoolean("showReport", false);
showPrPr = preferences.getBoolean("showPrPr", false);
showViewHistory = preferences.getBoolean("showViewHistory", true);
showAdminActions = preferences.getBoolean("showAdminActions", true);
showChangePermissions = preferences.getBoolean("showChangePermissions", true);
@ -187,14 +189,6 @@ public class NekoConfig {
editor.commit();
}
public static void toggleShowPrPr() {
showPrPr = !showPrPr;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showPrPr", showPrPr);
editor.commit();
}
public static void toggleShowAdminActions() {
showAdminActions = !showAdminActions;
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);

View File

@ -55,7 +55,6 @@ import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.SeekBarView;
import java.util.ArrayList;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import cn.hutool.core.util.StrUtil;
@ -246,7 +245,7 @@ public class NekoSettingsActivity extends BaseFragment {
}
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
if (UserConfig.getInstance(a).isClientActivated()) {
MessagesController.getInstance(a).checkProxyInfo(true);
MessagesController.getInstance(a).checkPromoInfo(true);
}
}
} else if (position == skipOpenLinkConfiirm) {
@ -334,7 +333,7 @@ public class NekoSettingsActivity extends BaseFragment {
BottomBuilder builder = new BottomBuilder(getParentActivity());
builder.addTitle(LocaleController.getString("CachePath",R.string.CachePath));
builder.addTitle(LocaleController.getString("CachePath", R.string.CachePath));
AtomicReference<String> target = new AtomicReference<>();
@ -834,7 +833,7 @@ public class NekoSettingsActivity extends BaseFragment {
linearLayoutInviteContainer.setOrientation(LinearLayout.VERTICAL);
linearLayout.addView(linearLayoutInviteContainer, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
int count = NekoXConfig.developerMode ? 10 : 9;
int count = NekoXConfig.developerMode ? 9 : 8;
for (int a = 0; a < count; a++) {
TextCheckCell textCell = new TextCheckCell(context);
switch (a) {
@ -851,30 +850,26 @@ public class NekoSettingsActivity extends BaseFragment {
break;
}
case 3: {
textCell.setTextAndCheck(LocaleController.getString("Prpr", R.string.Prpr), NekoConfig.showPrPr, false);
break;
}
case 4: {
textCell.setTextAndCheck(LocaleController.getString("ViewHistory", R.string.ViewHistory), NekoConfig.showViewHistory, false);
break;
}
case 5: {
case 4: {
textCell.setTextAndCheck(LocaleController.getString("Translate", R.string.Translate), NekoConfig.showTranslate, false);
break;
}
case 6: {
case 5: {
textCell.setTextAndCheck(LocaleController.getString("ReportChat", R.string.ReportChat), NekoConfig.showReport, false);
break;
}
case 7: {
case 6: {
textCell.setTextAndCheck(LocaleController.getString("EditAdminRights", R.string.EditAdminRights), NekoConfig.showAdminActions, false);
break;
}
case 8: {
case 7: {
textCell.setTextAndCheck(LocaleController.getString("ChangePermissions", R.string.ChangePermissions), NekoConfig.showChangePermissions, false);
break;
}
case 9: {
case 8: {
textCell.setTextAndCheck(LocaleController.getString("MessageDetails", R.string.MessageDetails), NekoConfig.showMessageDetails, false);
break;
}
@ -901,36 +896,31 @@ public class NekoSettingsActivity extends BaseFragment {
break;
}
case 3: {
NekoConfig.toggleShowPrPr();
textCell.setChecked(NekoConfig.showPrPr);
break;
}
case 4: {
NekoConfig.toggleShowViewHistory();
textCell.setChecked(NekoConfig.showViewHistory);
break;
}
case 5: {
case 4: {
NekoConfig.toggleShowTranslate();
textCell.setChecked(NekoConfig.showTranslate);
break;
}
case 6: {
case 5: {
NekoConfig.toggleShowReport();
textCell.setChecked(NekoConfig.showReport);
break;
}
case 7: {
case 6: {
NekoConfig.toggleShowAdminActions();
textCell.setChecked(NekoConfig.showAdminActions);
break;
}
case 8: {
case 7: {
NekoConfig.toggleShowChangePermissions();
textCell.setChecked(NekoConfig.showChangePermissions);
break;
}
case 9: {
case 8: {
NekoConfig.toggleShowMessageDetails();
textCell.setChecked(NekoConfig.showMessageDetails);
break;

View File

@ -0,0 +1,237 @@
package tw.nekomimi.nekogram.parts
import kotlinx.coroutines.*
import org.telegram.messenger.LocaleController
import org.telegram.messenger.R
import org.telegram.tgnet.TLRPC
import org.telegram.ui.ArticleViewer
import tw.nekomimi.nekogram.transtale.TranslateDb
import tw.nekomimi.nekogram.transtale.Translator
import tw.nekomimi.nekogram.utils.AlertUtil
import tw.nekomimi.nekogram.utils.AlertUtil.showTransFailedDialog
import tw.nekomimi.nekogram.utils.UIUtil.runOnUIThread
import java.lang.Runnable
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import kotlin.collections.HashMap
import kotlin.collections.HashSet
fun HashSet<Any>.filterBaseTexts(): HashSet<Any> {
var hasNext: Boolean
do {
hasNext = false
HashSet(this).forEach { item ->
when (item) {
is TLRPC.TL_textMarked -> {
remove(item)
add(item.text)
addAll(item.texts)
hasNext = true
}
is TLRPC.TL_textConcat -> {
remove(item)
addAll(item.texts)
hasNext = true
}
is TLRPC.TL_textFixed -> {
remove(item)
add(item.text)
addAll(item.texts)
hasNext = true
}
is TLRPC.TL_textSubscript -> {
remove(item)
add(item.text)
addAll(item.texts)
hasNext = true
}
is TLRPC.TL_textSuperscript -> {
remove(item)
add(item.text)
addAll(item.texts)
hasNext = true
}
is TLRPC.TL_textAnchor -> {
remove(item)
add(item.text)
addAll(item.texts)
hasNext = true
}
is TLRPC.RichText -> {
item.texts.takeIf { isNotEmpty() }?.also { addAll(it);hasNext = true; }
}
}
}
} while (hasNext)
return this
}
fun ArticleViewer.doTransLATE() {
val dialog = AlertUtil.showProgress(parentActivity)
dialog.show()
fun update(message: String) {
runOnUIThread(Runnable { dialog.setMessage(message) })
}
val transPool = newFixedThreadPoolContext(5, "Article Trans Pool")
val cancel = AtomicBoolean(false)
dialog.setOnCancelListener {
adapter[0].trans = false
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate)
cancel.set(true)
transPool.close()
}
GlobalScope.launch(Dispatchers.IO) {
val copy = HashMap(adapter[0].textToBlocks)
val array = HashSet(adapter[0].textBlocks).filterBaseTexts()
val errorCount = AtomicInteger()
val deferreds = LinkedList<Deferred<Unit>>()
val all = array.size
val taskCount = AtomicInteger(array.size)
update("0 / $all")
array.forEach { item ->
when (item) {
is TLRPC.RichText -> getText(adapter[0], null, item, item, copy[item] ?: copy[item.parentRichText], 1000, true).takeIf { it.isNotBlank() }?.toString()
is String -> item
else -> null
}?.also { str ->
deferreds.add(async(transPool) {
if (TranslateDb.contains(str)) {
update("${all - taskCount.get()} / $all")
if (taskCount.decrementAndGet() % 10 == 0) runOnUIThread(Runnable {
updatePaintSize()
})
return@async
}
runCatching {
if (cancel.get()) return@async
TranslateDb.save(str, Translator.translate(str))
update((all - taskCount.get()).toString() + " / " + all)
if (taskCount.decrementAndGet() % 10 == 0) runOnUIThread(Runnable {
updatePaintSize()
})
}.onFailure {
if (cancel.get()) return@async
if (errorCount.incrementAndGet() > 3) {
cancel.set(true)
runOnUIThread(Runnable {
cancel.set(true)
dialog.dismiss()
updatePaintSize()
adapter[0].trans = false
transMenu.setTextAndIcon(LocaleController.getString("Translate", R.string.Translate), R.drawable.ic_translate)
showTransFailedDialog(parentActivity, it is UnsupportedOperationException, it.message ?: it.javaClass.simpleName, Runnable { doTransLATE() })
})
}
}
})
}.also {
if (it == null) taskCount.decrementAndGet()
}
}
deferreds.awaitAll()
runOnUIThread(Runnable {
transPool.cancel()
if (!cancel.get()) {
updatePaintSize()
dialog.dismiss()
}
})
}
}

View File

@ -15,8 +15,11 @@ interface Translator {
@Throws(Exception::class)
@JvmStatic
@JvmOverloads
fun translate(to: Locale = LocaleController.getInstance().currentLocale, query: String): String {
fun translate(query: String) = translate(LocaleController.getInstance().currentLocale,query)
@Throws(Exception::class)
@JvmStatic
fun translate(to: Locale, query: String): String {
var toLang = to.language

View File

@ -3,6 +3,7 @@ package tw.nekomimi.nekogram.utils
import android.content.Context
import android.widget.LinearLayout
import android.widget.Toast
import org.telegram.messenger.AndroidUtilities
import org.telegram.messenger.ApplicationLoader
import org.telegram.messenger.LocaleController
import org.telegram.messenger.R
@ -46,6 +47,34 @@ object AlertUtil {
})
@JvmStatic
fun showCopyAlert(ctx: Context, text: String) = UIUtil.runOnUIThread(Runnable {
val builder = AlertDialog.Builder(ctx)
builder.setTitle(LocaleController.getString("Translate", R.string.Translate))
builder.setMessage(text)
builder.setNegativeButton(LocaleController.getString("Copy", R.string.Copy)) { _, _ ->
AndroidUtilities.addToClipboard(text)
AlertUtil.showToast(LocaleController.getString("TextCopied",R.string.TextCopied))
builder.dismissRunnable.run()
}
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK)) { _, _ ->
builder.dismissRunnable.run()
}
builder.show()
})
@JvmOverloads
@JvmStatic
fun showProgress(ctx: Context, text: String = LocaleController.getString("Loading", R.string.Loading)): AlertDialog {

View File

@ -6,7 +6,7 @@ buildscript {
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0-alpha08'
classpath 'com.android.tools.build:gradle:3.6.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.72"
classpath 'com.google.gms:google-services:4.3.3'
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0-beta04'

View File

@ -1,6 +1,6 @@
#Thu Apr 30 00:19:49 CST 2020
#Fri May 01 07:44:14 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.4-rc-3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip