mirror of https://github.com/NekoX-Dev/NekoX.git
This commit is contained in:
parent
c775d4f0e8
commit
a64472561f
|
@ -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']
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue