改进翻译

This commit is contained in:
世界 2020-05-02 23:21:45 +08:00
parent 94bee0be8c
commit f95784c0a6
No known key found for this signature in database
GPG Key ID: CD109927C34A63C4
41 changed files with 576 additions and 194 deletions

View File

@ -74,7 +74,7 @@ NekoX is an open source third-party Telegram android app.
- Allow auto disable proxy when VPN is enabled
- Add stickers without sticker pack
- Sticker set list backup / restore / share
- Instant View translation support
- Full InstantView translation support
- Delete all messages in group
- Dialog sorting is optional "Unread and can be prioritized for reminding" etc.
- Allow to skip "regret within five seconds"

View File

@ -3892,7 +3892,7 @@ public class MessagesController extends BaseController implements NotificationCe
promoDialogId = 0;
proxyDialogAddress = null;
nextPromoInfoCheckTime = getConnectionsManager().getCurrentTime() + 60 * 60;
getGlobalMainSettings().edit().putLong("proxy_dialog", promoDialogId).remove("proxyDialogAddress").putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime).commit();
getGlobalMainSettings().edit().putLong("proxy_dialog", promoDialogId).remove("proxyDialogAddress").putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime).apply();
});
removePromoDialog();
}
@ -4624,7 +4624,7 @@ public class MessagesController extends BaseController implements NotificationCe
editor.remove("promo_psa_type");
}
editor.putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime);
editor.commit();
editor.apply();
if (!noDialog) {
AndroidUtilities.runOnUIThread(() -> {
@ -4774,7 +4774,7 @@ public class MessagesController extends BaseController implements NotificationCe
}
if (noDialog) {
promoDialogId = 0;
getGlobalMainSettings().edit().putLong("proxy_dialog", promoDialogId).remove("proxyDialogAddress").putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime).commit();
getGlobalMainSettings().edit().putLong("proxy_dialog", promoDialogId).remove("proxyDialogAddress").putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime).apply();
checkingPromoInfoRequestId = 0;
checkingPromoInfo = false;
AndroidUtilities.runOnUIThread(this::removePromoDialog);
@ -4784,7 +4784,7 @@ public class MessagesController extends BaseController implements NotificationCe
promoDialogId = 0;
proxyDialogAddress = null;
nextPromoInfoCheckTime = getConnectionsManager().getCurrentTime() + 60 * 60;
getGlobalMainSettings().edit().putLong("proxy_dialog", promoDialogId).remove("proxyDialogAddress").putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime).commit();
getGlobalMainSettings().edit().putLong("proxy_dialog", promoDialogId).remove("proxyDialogAddress").putInt("nextPromoInfoCheckTime", nextPromoInfoCheckTime).apply();
AndroidUtilities.runOnUIThread(this::removePromoDialog);
}
}

View File

@ -2009,8 +2009,8 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
return spannableStringBuilder;
} else if (richText instanceof TLRPC.TL_textPlain) {
String plainText = ((TLRPC.TL_textPlain) richText).text;
if (!noTranslate && StrUtil.isNotBlank(plainText) && adapter.trans && TranslateDb.contains(plainText)) {
plainText = TranslateDb.query(plainText);
if (!noTranslate && StrUtil.isNotBlank(plainText) && adapter.trans && TranslateDb.currentTarget().contains(plainText)) {
plainText = TranslateDb.currentTarget().query(plainText);
}
return plainText;
} else if (richText instanceof TLRPC.TL_textAnchor) {
@ -2127,8 +2127,8 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
return getPlainText(((TLRPC.TL_textUrl) richText).text);
} else if (richText instanceof TLRPC.TL_textPlain) {
String plainText = ((TLRPC.TL_textPlain) richText).text;
if (plainText != null && Instance != null && Instance.adapter[0].trans && TranslateDb.contains(plainText)) {
plainText = TranslateDb.query(plainText);
if (plainText != null && Instance != null && Instance.adapter[0].trans && TranslateDb.currentTarget().contains(plainText)) {
plainText = TranslateDb.currentTarget().query(plainText);
}
return plainText;
} else if (richText instanceof TLRPC.TL_textAnchor) {
@ -2442,7 +2442,7 @@ public class ArticleViewer implements NotificationCenter.NotificationCenterDeleg
CharSequence text;
if (plainText != null) {
text = (parentAdapter.trans && TranslateDb.contains(plainText.toString())) ? TranslateDb.query(plainText.toString()) : plainText;
text = (parentAdapter.trans && TranslateDb.currentTarget().contains(plainText.toString())) ? TranslateDb.currentTarget().query(plainText.toString()) : plainText;
} else {
text = getText(parentAdapter, parentView, richText, richText, parentBlock, width);
}

View File

@ -68,6 +68,7 @@ import org.telegram.ui.Components.UndoView;
import java.io.File;
import java.util.ArrayList;
import tw.nekomimi.nekogram.transtale.TranslateDb;
import tw.nekomimi.nekogram.utils.FileUtil;
public class CacheControlActivity extends BaseFragment {
@ -623,6 +624,9 @@ public class CacheControlActivity extends BaseFragment {
database.executeFast("PRAGMA journal_size_limit = 0").stepThis().dispose();
database.executeFast("VACUUM").stepThis().dispose();
database.executeFast("PRAGMA journal_size_limit = -1").stepThis().dispose();
TranslateDb.clearAll();
} catch (Exception e) {
FileLog.e(e);
} finally {

View File

@ -1277,14 +1277,14 @@ public abstract class TextSelectionHelper<Cell extends TextSelectionHelper.Selec
if (NekoConfig.translationProvider < 0) {
TranslateBottomSheet.show(activity, urlFinal);
} else {
if (TranslateDb.contains(urlFinal)) {
AlertUtil.showCopyAlert(activity, TranslateDb.query(urlFinal));
if (TranslateDb.currentTarget().contains(urlFinal)) {
AlertUtil.showCopyAlert(activity, TranslateDb.currentTarget().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);
TranslateDb.currentTarget().save(urlFinal, translation);
pro.dismiss();
AlertUtil.showCopyAlert(activity, translation);
}

View File

@ -220,6 +220,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import tw.nekomimi.nekogram.MessageDetailsActivity;
import tw.nekomimi.nekogram.MessageHelper;
import tw.nekomimi.nekogram.NekoConfig;
@ -794,6 +795,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private final static int text_strike = 55;
private final static int text_underline = 56;
private final static int text_mention = 57;
private final static int text_transalte = 58;
private final static int search = 40;
@ -1569,6 +1571,11 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatActivityEnterView.getEditField().setSelectionOverride(editTextStart, editTextEnd);
chatActivityEnterView.getEditField().makeSelectedRegular();
}
} else if (id == text_transalte) {
if (chatActivityEnterView != null) {
chatActivityEnterView.getEditField().setSelectionOverride(editTextStart, editTextEnd);
chatActivityEnterView.getEditField().makeSelectedTranslate();
}
} else if (id == show_pinned) {
SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount);
preferences.edit().putInt("pin_" + dialog_id, 0).apply();
@ -1740,6 +1747,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
editTextItem.setTag(null);
editTextItem.setVisibility(View.GONE);
editTextItem.addSubItem(text_transalte, LocaleController.getString("Translate", R.string.Translate));
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(LocaleController.getString("Bold", R.string.Bold));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
editTextItem.addSubItem(text_bold, stringBuilder);
@ -3649,9 +3658,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
builder.setNeutralButton(LocaleController.getString("Hide", R.string.Hide), (dialogInterface, i) -> {
SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount);
if (chatInfo != null) {
preferences.edit().putInt("pin_" + dialog_id, chatInfo.pinned_msg_id).commit();
preferences.edit().putInt("pin_" + dialog_id, chatInfo.pinned_msg_id).apply();
} else if (userInfo != null) {
preferences.edit().putInt("pin_" + dialog_id, userInfo.pinned_msg_id).commit();
preferences.edit().putInt("pin_" + dialog_id, userInfo.pinned_msg_id).apply();
}
updatePinnedMessageView(true);
});
@ -3659,9 +3668,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
SharedPreferences preferences = MessagesController.getNotificationsSettings(currentAccount);
if (chatInfo != null) {
preferences.edit().putInt("pin_" + dialog_id, chatInfo.pinned_msg_id).commit();
preferences.edit().putInt("pin_" + dialog_id, chatInfo.pinned_msg_id).apply();
} else if (userInfo != null) {
preferences.edit().putInt("pin_" + dialog_id, userInfo.pinned_msg_id).commit();
preferences.edit().putInt("pin_" + dialog_id, userInfo.pinned_msg_id).apply();
}
updatePinnedMessageView(true);
}
@ -12521,10 +12530,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (!TextUtils.isEmpty(message)) {
if (topUndoView != null) {
if (type == MessagesController.PROMO_TYPE_PROXY) {
preferences.edit().putLong("proxychannel", dialog_id).commit();
preferences.edit().putLong("proxychannel", dialog_id).apply();
} else if (type == MessagesController.PROMO_TYPE_PSA) {
String psaType = getMessagesController().promoPsaType;
preferences.edit().putBoolean(psaType + "_shown", true).commit();
preferences.edit().putBoolean(psaType + "_shown", true).apply();
}
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(message);
MessageObject.addLinks(false, stringBuilder);
@ -12573,6 +12582,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (Build.VERSION.SDK_INT >= 23) {
menu.removeItem(android.R.id.shareText);
}
menu.add(R.id.menu_translate, R.id.menu_translate, 5, LocaleController.getString("Translate", R.string.Translate));
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(LocaleController.getString("Bold", R.string.Bold));
stringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0, stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
menu.add(R.id.menu_groupbolditalic, R.id.menu_bold, 6, stringBuilder);
@ -12597,6 +12609,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
menu.add(R.id.menu_groupbolditalic, R.id.menu_link, 11, LocaleController.getString("CreateLink", R.string.CreateLink));
menu.add(R.id.menu_groupbolditalic, R.id.menu_mention, 12, LocaleController.getString("CreateMention", R.string.CreateMention));
menu.add(R.id.menu_groupbolditalic, R.id.menu_regular, 13, LocaleController.getString("Regular", R.string.Regular));
}
private void updateScheduledInterface(boolean animated) {
@ -14558,13 +14571,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (selectedObject == null || i < 0 || i >= options.size()) {
return false;
}
if (processSelectedOptionLongClick(options.get(i))) {
int r = processSelectedOptionLongClick(cell, options.get(i));
if (r == 2) {
if (scrimPopupWindow != null) {
scrimPopupWindow.dismiss();
}
return true;
}
return false;
return r > 0;
});
}
scrollView.addView(linearLayout, LayoutHelper.createScroll(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
@ -15402,7 +15417,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (NekoConfig.translationProvider < 0) {
TranslateBottomSheet.show(getParentActivity(), original);
} else {
if (TranslateDb.contains(original)) {
if (TranslateDb.currentTarget().contains(original)) {
if (finalMessageCell != null) {
MessageObject messageObject = finalMessageCell.getMessageObject();
MessageHelper.setMessageContent(messageObject, finalMessageCell, original +
@ -15410,7 +15425,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
"\n" +
"--------" +
"\n" +
TranslateDb.query(original) +
TranslateDb.currentTarget().query(original) +
"\u200C\u200C");
chatAdapter.updateRowWithMessageObject(messageObject, true);
}
@ -15419,7 +15434,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
Translator.translate(original, new Translator.Companion.TranslateCallBack() {
@Override
public void onSuccess(@NotNull String translation) {
TranslateDb.save(original, translation);
TranslateDb.currentTarget().save(original, translation);
if (getParentActivity() != null && finalMessageCell != null) {
MessageObject messageObject = finalMessageCell.getMessageObject();
MessageHelper.setMessageContent(messageObject, finalMessageCell, original +
@ -15593,8 +15608,96 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
selectedObjectToEditCaption = null;
}
private boolean processSelectedOptionLongClick(int option) {
private int processSelectedOptionLongClick(ActionBarMenuSubItem cell, int option) {
switch (option) {
case 88: {
ChatMessageCell messageCell = null;
int count = chatListView.getChildCount();
for (int a = 0; a < count; a++) {
View child = chatListView.getChildAt(a);
if (child instanceof ChatMessageCell) {
ChatMessageCell c = (ChatMessageCell) child;
if (c.getMessageObject() == selectedObject) {
messageCell = c;
break;
}
}
}
if (messageCell == null) return 0;
String original = selectedObject.messageOwner.message;
Matcher matcher = Pattern.compile("\u200C\u200C\\n\\n--------\\n.*\u200C\u200C", Pattern.DOTALL).matcher(original);
if (matcher.find()) return 0;
ChatMessageCell finalMessageCell = messageCell;
Translator.showTargetLangSelect(cell, 0, (locale) -> {
if (scrimPopupWindow != null) {
scrimPopupWindow.dismiss();
scrimPopupWindow = null;
scrimPopupWindowItems = null;
}
if (NekoConfig.translationProvider < 0) {
TranslateBottomSheet.show(getParentActivity(), original);
} else {
if (TranslateDb.forLocale(locale).contains(original)) {
MessageObject messageObject = finalMessageCell.getMessageObject();
MessageHelper.setMessageContent(messageObject, finalMessageCell, original +
"\u200C\u200C\n" +
"\n" +
"--------" +
"\n" +
TranslateDb.forLocale(locale).query(original) +
"\u200C\u200C");
chatAdapter.updateRowWithMessageObject(messageObject, true);
} else {
Translator.translate(locale,original, new Translator.Companion.TranslateCallBack() {
@Override
public void onSuccess(@NotNull String translation) {
TranslateDb.forLocale(locale).save(original, translation);
if (getParentActivity() != null) {
MessageObject messageObject = finalMessageCell.getMessageObject();
MessageHelper.setMessageContent(messageObject, finalMessageCell, original +
"\u200C\u200C\n" +
"\n" +
"--------" +
"\n" +
translation +
"\u200C\u200C");
chatAdapter.updateRowWithMessageObject(messageObject, true);
}
}
@Override
public void onFailed(boolean unsupported, @NotNull String message) {
Activity parentActivity = getParentActivity();
if (parentActivity != null) {
AlertUtil.showTransFailedDialog(getParentActivity(), unsupported, message, () -> {
if (NekoConfig.translationProvider < 0) {
TranslateBottomSheet.show(getParentActivity(), original);
} else {
Translator.translate(original, this);
}
});
}
}
});
}
}
return Unit.INSTANCE;
});
return 1;
}
case 94: {
ArrayList<MessageObject> messages = new ArrayList<>();
messages.add(selectedObject);
@ -15617,12 +15720,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
SendMessagesHelper.getInstance(currentAccount).sendMessage(toSend.toString(), dialog_id, selectedObject, null, false,
null, null, null, true, 0);
return true;
return 2;
}
}
}
}
return false;
return 0;
}
@Override

View File

@ -124,7 +124,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
private boolean scrolling;
private View loadingMapView;
private FrameLayout mapViewClip;
private LocationActivityAdapter adapter;
private RecyclerListView listView;
@ -506,9 +505,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
};
mapViewClip.setWillNotDraw(false);
loadingMapView = new View(context);
loadingMapView.setBackgroundDrawable(new MapPlaceholderDrawable());
searchAreaButton = new SearchButton(context);
searchAreaButton.setTranslationX(-AndroidUtilities.dp(80));
searchAreaButton.setVisibility(INVISIBLE);
@ -869,7 +865,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
};
AndroidUtilities.runOnUIThread(() -> {
if (mapView != null && getParentActivity() != null) {
mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), AndroidUtilities.dp(10));
onMapInit();
mapsInitialized = true;
if (isActiveThemeDark()) {
@ -1283,7 +1278,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
showSearchPlacesButton(true);
removeInfoView();
if (!scrolling && (locationType == LOCATION_TYPE_SEND || locationType == LOCATION_TYPE_SEND_WITH_LIVE) && listView.getChildCount() > 0) {
if (!scrolling && listView.getChildCount() > 0) {
View view = listView.getChildAt(0);
if (view != null) {
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(view);
@ -1362,6 +1357,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
FileLog.e(e);
}
}
updateClipView();
}
private void removeInfoView() {
@ -1462,7 +1458,7 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
mapViewClip.setTranslationY(top - nonClipSize);
if (mapView != null) {
mapView.setPadding(AndroidUtilities.dp(70), 0, AndroidUtilities.dp(70), AndroidUtilities.dp(10));
mapView.setPadding(0, AndroidUtilities.dp(6), 0, clipSize + AndroidUtilities.dp(6));
}
if (overlayView != null) {
overlayView.setTranslationY(trY);
@ -1484,7 +1480,8 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
location = null;
}
if (location != null) {
// TODO: googleMap.moveCamera(CameraUpdateFactory.newLatLng(location));
final IMapController controller = mapView.getController();
controller.setCenter(location);
}
}
}
@ -1605,7 +1602,6 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
if (mapView.getParent() == null) {
mapViewClip.addView(mapView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, overScrollHeight + AndroidUtilities.dp(10), Gravity.TOP | Gravity.LEFT));
mapViewClip.addView(overlayView, 1, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, overScrollHeight + AndroidUtilities.dp(10), Gravity.TOP | Gravity.LEFT));
mapViewClip.addView(loadingMapView, 2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
}
searchItem.setVisibility(VISIBLE);
@ -1738,4 +1734,4 @@ public class ChatAttachAlertLocationLayout extends ChatAttachAlert.AttachAlertLa
return themeDescriptions;
}
}
}

View File

@ -32,6 +32,7 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.inputmethod.EditorInfo;
import android.widget.FrameLayout;
import org.jetbrains.annotations.NotNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
@ -40,6 +41,13 @@ import org.telegram.messenger.R;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.Theme;
import tw.nekomimi.nekogram.NekoConfig;
import tw.nekomimi.nekogram.transtale.TranslateBottomSheet;
import tw.nekomimi.nekogram.transtale.TranslateDb;
import tw.nekomimi.nekogram.transtale.Translator;
import tw.nekomimi.nekogram.transtale.TranslatorKt;
import tw.nekomimi.nekogram.utils.AlertUtil;
public class EditTextCaption extends EditTextBoldCursor {
private String caption;
@ -112,6 +120,48 @@ public class EditTextCaption extends EditTextBoldCursor {
applyTextStyleToSelection(new TextStyleSpan(run));
}
public void makeSelectedTranslate() {
int start = getSelectionStart();
int end = getSelectionEnd();
String text = getText().subSequence(start,end).toString();
if (TranslateDb.currentInputTarget().contains(text)) {
getText().replace(start,end, TranslateDb.currentInputTarget().query(text));
} else {
if (NekoConfig.translationProvider < 0) {
TranslateBottomSheet.show(getContext(), text);
} else {
AlertDialog pro = AlertUtil.showProgress(getContext());
pro.show();
Translator.translate(TranslatorKt.getCode2Locale(NekoConfig.translateInputLang), text, new Translator.Companion.TranslateCallBack() {
@Override public void onSuccess(@NotNull String translation) {
pro.dismiss();
getText().replace(start,end, translation);
TranslateDb.currentInputTarget().save(text, translation);
}
@Override public void onFailed(boolean unsupported, @NotNull String message) {
pro.dismiss();
AlertUtil.showTransFailedDialog(getContext(), unsupported, message, () -> {
pro.show();
Translator.translate(text, this);
});
}
});
}
}
}
public void makeSelectedMention() {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
@ -355,11 +405,14 @@ public class EditTextCaption extends EditTextBoldCursor {
makeSelectedUnderline();
mode.finish();
return true;
} else if (item.getItemId() == R.id.menu_translate) {
makeSelectedTranslate();
mode.finish();
return true;
}
try {
return callback.onActionItemClicked(mode, item);
} catch (Exception ignore) {
}
return true;
}

View File

@ -150,6 +150,11 @@ public class ContentPreviewViewer {
icons.add(R.drawable.deproko_baseline_send_24);
actions.add(0);
}
if (delegate.needSend() && !delegate.isInScheduleMode()) {
items.add(LocaleController.getString("SendWithoutSound", R.string.SendWithoutSound));
icons.add(R.drawable.input_notify_off);
actions.add(100);
}
if (delegate.canSchedule()) {
items.add(LocaleController.getString("Schedule", R.string.Schedule));
icons.add(R.drawable.baseline_timer_24);
@ -182,9 +187,9 @@ public class ContentPreviewViewer {
if (parentActivity == null) {
return;
}
if (actions.get(which) == 0) {
if (actions.get(which) == 0 || actions.get(which) == 100) {
if (delegate != null) {
delegate.sendSticker(currentDocument, parentObject, true, 0);
delegate.sendSticker(currentDocument, parentObject, actions.get(which) == 0, 0);
}
} else if (actions.get(which) == 1) {
if (delegate != null) {
@ -238,6 +243,11 @@ public class ContentPreviewViewer {
icons.add(R.drawable.deproko_baseline_send_24);
actions.add(0);
}
if (delegate.needSend() && !delegate.isInScheduleMode()) {
items.add(LocaleController.getString("SendWithoutSound", R.string.SendWithoutSound));
icons.add(R.drawable.input_notify_off);
actions.add(100);
}
if (delegate.canSchedule()) {
items.add(LocaleController.getString("Schedule", R.string.Schedule));
icons.add(R.drawable.baseline_timer_24);
@ -267,8 +277,8 @@ public class ContentPreviewViewer {
if (parentActivity == null) {
return;
}
if (actions.get(which) == 0) {
delegate.sendGif(currentDocument != null ? currentDocument : inlineResult, true, 0);
if (actions.get(which) == 0 || actions.get(which) == 100) {
delegate.sendGif(currentDocument != null ? currentDocument : inlineResult, actions.get(which) == 0, 0);
} else if (actions.get(which) == 1) {
MediaDataController.getInstance(currentAccount).removeRecentGif(currentDocument);
delegate.gifAddedOrDeleted();

View File

@ -826,7 +826,7 @@ public class DataAutoDownloadActivity extends BaseFragment {
}
SharedPreferences.Editor editor = MessagesController.getMainSettings(currentAccount).edit();
editor.putInt(key2, currentPresetNum);
editor.commit();
editor.apply();
DownloadController.getInstance(currentAccount).checkAutodownloadSettings();
for (int a = 0; a < 3; a++) {
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(photosRow + a);

View File

@ -164,14 +164,12 @@ public class LanguageSelectActivity extends BaseFragment implements Notification
if (localeInfo.toInstall) {
AlertsCreator.createLanguageAlert((LaunchActivity) getParentActivity(),localeInfo.pack,() -> {
finishFragment();
UIUtil.runOnIoDispatcher(TranslateDb::clear);
}).show();
return;
}
LocaleController.getInstance().applyLanguage(localeInfo, true, false, false, true, currentAccount);
parentLayout.rebuildAllFragmentViews(false, false);
}
UIUtil.runOnIoDispatcher(TranslateDb::clear);
finishFragment();
});

View File

@ -701,7 +701,7 @@ public class PrivacyControlActivity extends BaseFragment implements Notification
} else {
nobodyRow = rowCount++;
}
if (rulesType == PRIVACY_RULES_TYPE_PHONE && currentType == TYPE_NOBODY) {
if (rulesType == PRIVACY_RULES_TYPE_PHONE/* && currentType == TYPE_NOBODY*/) {
phoneDetailRow = rowCount++;
phoneSectionRow = rowCount++;
phoneEverybodyRow = rowCount++;

View File

@ -4,16 +4,19 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Environment;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationsService;
import org.telegram.messenger.R;
import java.lang.reflect.Method;
import java.util.Locale;
import cn.hutool.core.util.StrUtil;
import tw.nekomimi.nekogram.transtale.TranslateDb;
import tw.nekomimi.nekogram.utils.UIUtil;
@SuppressLint("ApplySharedPref")
public class NekoConfig {
private static SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
@ -91,8 +94,29 @@ public class NekoConfig {
public static String cachePath;
public static String translateToLang;
public static String translateInputLang = "en";
public static String translateInputLang;
public static String formatLang(String name) {
if (name == null) {
return LocaleController.getString("Default", R.string.Default);
} else {
if (name.contains("-")) {
return new Locale(StrUtil.subBefore(name, "-", false), StrUtil.subAfter(name, "-", false)).getDisplayName(LocaleController.getInstance().currentLocale);
} else {
return new Locale(name).getDisplayName(LocaleController.getInstance().currentLocale);
}
}
}
static {
@ -160,8 +184,11 @@ public class NekoConfig {
useDefaultTheme = preferences.getBoolean("use_default_theme", false);
showIdAndDc = preferences.getBoolean("show_id_and_dc", false);
googleCloudTranslateKey = preferences.getString("google_cloud_translate_key",null);
cachePath = preferences.getString("cache_path",null);
googleCloudTranslateKey = preferences.getString("google_cloud_translate_key", null);
cachePath = preferences.getString("cache_path", null);
translateToLang = preferences.getString("trans_to_lang", null);
translateInputLang = preferences.getString("trans_input_to_lang", "en");
}
@ -170,7 +197,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showAddToSavedMessages", showAddToSavedMessages);
editor.commit();
editor.apply();
}
public static void toggleShowReport() {
@ -178,7 +205,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showReport", showReport);
editor.commit();
editor.apply();
}
public static void toggleShowViewHistory() {
@ -186,7 +213,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showViewHistory", showViewHistory);
editor.commit();
editor.apply();
}
public static void toggleShowAdminActions() {
@ -194,7 +221,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showAdminActions", showAdminActions);
editor.commit();
editor.apply();
}
public static void toggleShowChangePermissions() {
@ -202,7 +229,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showChangePermissions", showChangePermissions);
editor.commit();
editor.apply();
}
public static void toggleShowDeleteDownloadedFile() {
@ -210,7 +237,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showDeleteDownloadedFile", showDeleteDownloadedFile);
editor.commit();
editor.apply();
}
public static void toggleShowMessageDetails() {
@ -218,7 +245,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showMessageDetails", showMessageDetails);
editor.commit();
editor.apply();
}
public static void toggleShowRepeat() {
@ -226,7 +253,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showRepeat", showRepeat);
editor.commit();
editor.apply();
}
public static void toggleIPv6() {
@ -234,7 +261,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("useIPv6", useIPv6);
editor.commit();
editor.apply();
}
public static void toggleHidePhone() {
@ -242,7 +269,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("hidePhone", hidePhone);
editor.commit();
editor.apply();
}
public static void toggleIgnoreBlocked() {
@ -250,7 +277,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("ignoreBlocked", ignoreBlocked);
editor.commit();
editor.apply();
}
public static void toggleForceTablet() {
@ -258,7 +285,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("forceTablet", forceTablet);
editor.commit();
editor.apply();
}
public static void toggleTypeface() {
@ -266,7 +293,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("typeface", typeface);
editor.commit();
editor.apply();
}
public static void setNameOrder(int order) {
@ -274,7 +301,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("nameOrder", nameOrder);
editor.commit();
editor.apply();
LocaleController.getInstance().recreateFormatters();
}
@ -284,7 +311,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("mapPreviewProvider", mapPreviewProvider);
editor.commit();
editor.apply();
}
public static void toggleTransparentStatusBar() {
@ -292,7 +319,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("transparentStatusBar", transparentStatusBar);
editor.commit();
editor.apply();
}
public static void toggleResidentNotification() {
@ -300,7 +327,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("residentNotification", residentNotification);
editor.commit();
editor.apply();
ApplicationLoader.applicationContext.stopService(new Intent(ApplicationLoader.applicationContext, NotificationsService.class));
ApplicationLoader.startPushService();
}
@ -310,7 +337,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("hideProxySponsorChannel", hideProxySponsorChannel);
editor.commit();
editor.apply();
}
public static void setEventType(int type) {
@ -318,7 +345,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("eventType", eventType);
editor.commit();
editor.apply();
}
public static void setActionBarDecoration(int decoration) {
@ -326,7 +353,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("actionBarDecoration", actionBarDecoration);
editor.commit();
editor.apply();
}
public static void toggleNewYear() {
@ -334,7 +361,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("newYear", newYear);
editor.commit();
editor.apply();
}
public static void toggleUnlimitedFavedStickers() {
@ -342,7 +369,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("unlimitedFavedStickers", unlimitedFavedStickers);
editor.commit();
editor.apply();
}
public static void toggleUnlimitedPinnedDialogs() {
@ -350,7 +377,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("unlimitedPinnedDialogs", unlimitedPinnedDialogs);
editor.commit();
editor.apply();
}
public static void toggleShowTranslate() {
@ -358,7 +385,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showTranslate", showTranslate);
editor.commit();
editor.apply();
}
public static void setStickerSize(float size) {
@ -366,7 +393,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putFloat("stickerSize", stickerSize);
editor.commit();
editor.apply();
}
public static void setTranslationProvider(int provider) {
@ -374,8 +401,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putInt("translationProvider", translationProvider);
editor.commit();
UIUtil.runOnIoDispatcher(TranslateDb::clear);
editor.apply();
}
public static void toggleDisablePhotoSideAction() {
@ -383,7 +409,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("disablePhotoSideAction", disablePhotoSideAction);
editor.commit();
editor.apply();
}
public static void toggleOpenArchiveOnPull() {
@ -391,7 +417,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("openArchiveOnPull", openArchiveOnPull);
editor.commit();
editor.apply();
}
/*public static void toggleShowHiddenFeature() {
@ -407,7 +433,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("hideKeyboardOnChatScroll", hideKeyboardOnChatScroll);
editor.commit();
editor.apply();
}
public static void toggleAvatarAsDrawerBackground() {
@ -415,20 +441,20 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("avatarAsDrawerBackground", avatarAsDrawerBackground);
editor.commit();
editor.apply();
}
public static void toggleUseSystemEmoji() {
preferences.edit().putBoolean("useSystemEmoji", useSystemEmoji = !useSystemEmoji).commit();
preferences.edit().putBoolean("useSystemEmoji", useSystemEmoji = !useSystemEmoji).apply();
}
public static void toggleDisableChatAction() {
preferences.edit().putBoolean("disable_chat_action", disableChatAction = !disableChatAction).commit();
preferences.edit().putBoolean("disable_chat_action", disableChatAction = !disableChatAction).apply();
}
public static void toggleSortByUnread() {
preferences.edit().putBoolean("sort_by_unread", sortByUnread = !sortByUnread).commit();
preferences.edit().putBoolean("sort_by_unread", sortByUnread = !sortByUnread).apply();
}
@ -437,7 +463,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("showTabsOnForward", showTabsOnForward);
editor.commit();
editor.apply();
}
public static void toggleChatMessageAnimation() {
@ -445,7 +471,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("chatMessageAnimation", chatMessageAnimation);
editor.commit();
editor.apply();
}
public static void toggleRearVideoMessages() {
@ -453,7 +479,7 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("rearVideoMessages", rearVideoMessages);
editor.commit();
editor.apply();
}
public static void toggleHideAllTab() {
@ -461,126 +487,126 @@ public class NekoConfig {
SharedPreferences preferences = ApplicationLoader.applicationContext.getSharedPreferences("nekoconfig", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putBoolean("hideAllTab", hideAllTab);
editor.commit();
editor.apply();
}
public static void toggleSortByUnmuted() {
preferences.edit().putBoolean("sort_by_unmuted", sortByUnmuted = !sortByUnmuted).commit();
preferences.edit().putBoolean("sort_by_unmuted", sortByUnmuted = !sortByUnmuted).apply();
}
public static void toggleSortByUser() {
preferences.edit().putBoolean("sort_by_user", sortByUser = !sortByUser).commit();
preferences.edit().putBoolean("sort_by_user", sortByUser = !sortByUser).apply();
}
public static void toggleSortByContacts() {
preferences.edit().putBoolean("sort_by_contacts", sortByContacts = !sortByContacts).commit();
preferences.edit().putBoolean("sort_by_contacts", sortByContacts = !sortByContacts).apply();
}
public static void toggleDisableUndo() {
preferences.edit().putBoolean("disable_undo", disableUndo = !disableUndo).commit();
preferences.edit().putBoolean("disable_undo", disableUndo = !disableUndo).apply();
}
public static void toggleFilterUsers() {
preferences.edit().putBoolean("filter_users", filterUsers = !filterUsers).commit();
preferences.edit().putBoolean("filter_users", filterUsers = !filterUsers).apply();
}
public static void toggleFilterContacts() {
preferences.edit().putBoolean("filter_contacts", filterContacts = !filterContacts).commit();
preferences.edit().putBoolean("filter_contacts", filterContacts = !filterContacts).apply();
}
public static void toggleFilterGroups() {
preferences.edit().putBoolean("filterGroups", filterGroups = !filterGroups).commit();
preferences.edit().putBoolean("filterGroups", filterGroups = !filterGroups).apply();
}
public static void toggleFilterChannels() {
preferences.edit().putBoolean("filter_channels", filterChannels = !filterChannels).commit();
preferences.edit().putBoolean("filter_channels", filterChannels = !filterChannels).apply();
}
public static void toggleFilterBots() {
preferences.edit().putBoolean("filter_bots", filterBots = !filterBots).commit();
preferences.edit().putBoolean("filter_bots", filterBots = !filterBots).apply();
}
public static void toggleFilterAdmins() {
preferences.edit().putBoolean("filter_admins", filterAdmins = !filterAdmins).commit();
preferences.edit().putBoolean("filter_admins", filterAdmins = !filterAdmins).apply();
}
public static void toggleFilterUnmuted() {
preferences.edit().putBoolean("filter_unmuted", filterUnmuted = !filterUnmuted).commit();
preferences.edit().putBoolean("filter_unmuted", filterUnmuted = !filterUnmuted).apply();
}
public static void toggleDisableFilterUnread() {
preferences.edit().putBoolean("filter_unread", filterUnread = !filterUnread).commit();
preferences.edit().putBoolean("filter_unread", filterUnread = !filterUnread).apply();
}
public static void toggleFilterUnmutedAndUnread() {
preferences.edit().putBoolean("filter_unmuted_and_unread", filterUnmutedAndUnread = !filterUnmutedAndUnread).commit();
preferences.edit().putBoolean("filter_unmuted_and_unread", filterUnmutedAndUnread = !filterUnmutedAndUnread).apply();
}
public static void toggleDisableSystemAccount() {
preferences.edit().putBoolean("disable_system_account", disableSystemAccount = !disableSystemAccount).commit();
preferences.edit().putBoolean("disable_system_account", disableSystemAccount = !disableSystemAccount).apply();
}
public static void toggleDisableProxyWhenVpnEnabled() {
preferences.edit().putBoolean("disable_proxy_when_vpn_enabled", disableProxyWhenVpnEnabled = !disableProxyWhenVpnEnabled).commit();
preferences.edit().putBoolean("disable_proxy_when_vpn_enabled", disableProxyWhenVpnEnabled = !disableProxyWhenVpnEnabled).apply();
}
public static void toggleSkipOpenLinkConfirm() {
preferences.edit().putBoolean("skip_open_link_confirm", skipOpenLinkConfirm = !skipOpenLinkConfirm).commit();
preferences.edit().putBoolean("skip_open_link_confirm", skipOpenLinkConfirm = !skipOpenLinkConfirm).apply();
}
public static void toggleRemoveTitleEmoji() {
preferences.edit().putBoolean("remove_title_emoji", removeTitleEmoji = !removeTitleEmoji).commit();
preferences.edit().putBoolean("remove_title_emoji", removeTitleEmoji = !removeTitleEmoji).apply();
}
public static void toggleIgnoredMutedCount() {
preferences.edit().putBoolean("ignore_muted_count", ignoreMutedCount = !ignoreMutedCount).commit();
preferences.edit().putBoolean("ignore_muted_count", ignoreMutedCount = !ignoreMutedCount).apply();
}
public static void toggleUseDefaultTheme() {
preferences.edit().putBoolean("use_default_theme", useDefaultTheme = !useDefaultTheme).commit();
preferences.edit().putBoolean("use_default_theme", useDefaultTheme = !useDefaultTheme).apply();
}
public static void toggleShowIdAndDc() {
preferences.edit().putBoolean("show_id_and_dc", showIdAndDc = !showIdAndDc).commit();
preferences.edit().putBoolean("show_id_and_dc", showIdAndDc = !showIdAndDc).apply();
}
@ -596,5 +622,16 @@ public class NekoConfig {
}
public static void setTranslateToLang(String toLang) {
preferences.edit().putString("trans_to_lang", translateToLang = toLang).apply();
}
public static void setTranslateInputToLang(String toLang) {
preferences.edit().putString("trans_input_to_lang", translateInputLang = toLang).apply();
}
}

View File

@ -55,10 +55,13 @@ 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.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import kotlin.Unit;
import tw.nekomimi.nekogram.transtale.Translator;
import tw.nekomimi.nekogram.utils.EnvUtil;
import tw.nekomimi.nekogram.utils.PopupBuilder;
@ -103,6 +106,8 @@ public class NekoSettingsActivity extends BaseFragment {
private int transRow;
private int translationProviderRow;
private int translateToLangRow;
private int translateInputToLangRow;
private int googleCloudTranslateKeyRow;
private int trans2Row;
@ -498,6 +503,16 @@ public class NekoSettingsActivity extends BaseFragment {
builder.show();
} else if (position == translateToLangRow || position == translateInputToLangRow) {
Translator.showTargetLangSelect(view,position == translateToLangRow ? 1: 2,(locale) -> {
listAdapter.notifyItemChanged(position);
return Unit.INSTANCE;
});
} else if (position == googleCloudTranslateKeyRow) {
BottomBuilder builder = new BottomBuilder(getParentActivity());
@ -671,6 +686,8 @@ public class NekoSettingsActivity extends BaseFragment {
transRow = rowCount++;
translationProviderRow = rowCount++;
translateToLangRow = rowCount++;
translateInputToLangRow = rowCount++;
googleCloudTranslateKeyRow = rowCount++;
trans2Row = rowCount++;
@ -1181,6 +1198,10 @@ public class NekoSettingsActivity extends BaseFragment {
textCell.setText(LocaleController.getString("MessageMenu", R.string.MessageMenu), true);
} else if (position == sortMenuRow) {
textCell.setText(LocaleController.getString("SortMenu", R.string.SortMenu), true);
} else if (position == translateToLangRow) {
textCell.setTextAndValue(LocaleController.getString("TransToLang", R.string.TransToLang), NekoConfig.formatLang(NekoConfig.translateToLang), true);
} else if (position == translateInputToLangRow) {
textCell.setTextAndValue(LocaleController.getString("TransInputToLang", R.string.TransInputToLang), NekoConfig.formatLang(NekoConfig.translateInputLang), true);
} else if (position == googleCloudTranslateKeyRow) {
textCell.setText(LocaleController.getString("GoogleCloudTransKey", R.string.GoogleCloudTransKey), true);
} else if (position == deleteAccountRow) {
@ -1331,7 +1352,7 @@ public class NekoSettingsActivity extends BaseFragment {
position == hideProxySponsorChannelRow || position == skipOpenLinkConfiirm ||
position == disableFilteringRow || position == stickerSizeRow ||
position == unlimitedFavedStickersRow || position == messageMenuRow || position == deleteAccountRow ||
position == translationProviderRow || position == googleCloudTranslateKeyRow ||
position == translationProviderRow || position == translateToLangRow || position == translateInputToLangRow || position == googleCloudTranslateKeyRow ||
position == smoothKeyboardRow || position == pauseMusicOnRecordRow ||
position == disablePhotoSideActionRow || position == unlimitedPinnedDialogsRow || position == openArchiveOnPullRow ||
position == hideKeyboardOnChatScrollRow || position == sortMenuRow || position == disableSystemAccountRow ||
@ -1382,7 +1403,8 @@ public class NekoSettingsActivity extends BaseFragment {
if (position == connection2Row || position == dialogs2Row || position == chat2Row || position == trans2Row || position == experiment2Row || position == privacy2Row) {
return 1;
} else if (position == nameOrderRow || position == mapPreviewRow || position == stickerSizeRow || position == messageMenuRow ||
position == sortMenuRow || position == googleCloudTranslateKeyRow || position == cachePathRow ||
position == sortMenuRow || position == cachePathRow || position == googleCloudTranslateKeyRow ||
position == translateToLangRow || position == translateInputToLangRow ||
position == deleteAccountRow || position == translationProviderRow || position == eventTypeRow || position == actionBarDecorationRow) {
return 2;
} else if (position == ipv6Row || position == disableProxyWhenVpnEnabledRow || position == hidePhoneRow || position == disableUndoRow || position == inappCameraRow || position == disableChatActionRow ||

View File

@ -117,7 +117,7 @@ fun ArticleViewer.doTransLATE() {
deferreds.add(async(transPool) {
if (TranslateDb.contains(str)) {
if (TranslateDb.currentTarget().contains(str)) {
update("${all - taskCount.get()} / $all")
@ -135,7 +135,7 @@ fun ArticleViewer.doTransLATE() {
if (cancel.get()) return@async
TranslateDb.save(str, Translator.translate(str))
TranslateDb.currentTarget().save(str, Translator.translate(str))
update((all - taskCount.get()).toString() + " / " + all)

View File

@ -1,43 +1,57 @@
package tw.nekomimi.nekogram.transtale
import org.dizitart.no2.filters.Filters
import org.dizitart.no2.objects.ObjectRepository
import org.dizitart.no2.objects.filters.ObjectFilters
import tw.nekomimi.nekogram.database.mkCacheDatabase
import org.telegram.messenger.LocaleController
import tw.nekomimi.nekogram.NekoConfig
import tw.nekomimi.nekogram.database.mkDatabase
import java.util.*
import kotlin.collections.HashMap
object TranslateDb {
class TranslateDb(val code: String) {
val db = mkCacheDatabase("translate_caches")
var conn = db.getRepository("trans", TransItem::class.java)
var conn: ObjectRepository<TransItem> = db.getRepository(code, TransItem::class.java)
@JvmStatic
fun clear() {
companion object {
conn.remove(ObjectFilters.ALL)
val db = mkDatabase("translate_caches")
val repo = HashMap<Locale, TranslateDb>()
@JvmStatic fun currentTarget() = NekoConfig.translateToLang?.transDbByCode ?: LocaleController.getInstance().currentLocale.transDb
@JvmStatic fun forLocale(locale: Locale) = locale.transDb
@JvmStatic fun currentInputTarget() = NekoConfig.translateInputLang.transDbByCode
@JvmStatic fun clearAll() {
db.listRepositories().map { it.transDbByCode }.forEach { it.clear() }
repo.clear()
}
}
@JvmStatic
fun contains(text: String) = conn.find(ObjectFilters.eq("text", text)).count() > 0
fun clear() = synchronized<Unit>(this) {
@JvmStatic
fun save(text: String, trans: String) {
conn.drop()
conn = db.getRepository(code, TransItem::class.java)
}
fun contains(text: String) = synchronized(this) { conn.find(ObjectFilters.eq("text", text)).count() > 0 }
fun save(text: String, trans: String) = synchronized<Unit>(this) {
conn.update(TransItem(text, trans), true)
}
@JvmStatic
fun query(text: String): String? {
fun query(text: String) = synchronized<String?>(this) {
val result = conn.find(ObjectFilters.eq("text", text));
runCatching {
return result.first().trans!!
}
return null
return conn.find(ObjectFilters.eq("text", text)).firstOrDefault().trans
}

View File

@ -1,12 +1,53 @@
package tw.nekomimi.nekogram.transtale
import org.telegram.messenger.FileLog
import android.view.View
import cn.hutool.core.util.ArrayUtil
import cn.hutool.core.util.StrUtil
import org.apache.commons.lang3.LocaleUtils
import org.telegram.messenger.LocaleController
import org.telegram.messenger.R
import tw.nekomimi.nekogram.NekoConfig
import tw.nekomimi.nekogram.transtale.source.*
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.utils.UIUtil
import tw.nekomimi.nekogram.utils.receive
import tw.nekomimi.nekogram.utils.receiveLazy
import java.util.*
val String.code2Locale: Locale by receiveLazy<String, Locale> {
val args = replace('-', '_').split('_')
if (args.size == 1) Locale(args[0]) else Locale(args[0], args[1])
}
val Locale.locale2code by receiveLazy<Locale, String> {
if (StrUtil.isBlank(getCountry())) {
language
} else {
"$language-$country"
}
}
val LocaleController.LocaleInfo.locale by receiveLazy<LocaleController.LocaleInfo, Locale> { pluralLangCode.code2Locale }
val Locale.transDb by receive<Locale, TranslateDb> {
TranslateDb.repo[this] ?: TranslateDb(locale2code).also {
TranslateDb.repo[this] = it
}
}
val String.transDbByCode by receive<String, TranslateDb> { code2Locale.transDb }
interface Translator {
fun doTranslate(from: String, to: String, query: String): String
@ -15,7 +56,7 @@ interface Translator {
@Throws(Exception::class)
@JvmStatic
fun translate(query: String) = translate(LocaleController.getInstance().currentLocale,query)
fun translate(query: String) = translate(NekoConfig.translateToLang?.code2Locale ?: LocaleController.getInstance().currentLocale, query)
@Throws(Exception::class)
@JvmStatic
@ -27,7 +68,7 @@ interface Translator {
if (to.language == "zh" && (to.country.toUpperCase() == "CN" || to.country.toUpperCase() == "TW")) {
toLang = to.language + "-" + to.country.toUpperCase()
} else if (to.language == "pt" && to.country in arrayOf("PT","BR")) {
} else if (to.language == "pt" && to.country in arrayOf("PT", "BR")) {
toLang = to.language + "-" + to.country.toUpperCase()
}
@ -40,12 +81,87 @@ interface Translator {
else -> throw IllegalArgumentException()
}
// FileLog.d("[Trans] use provider ${translator.javaClass.simpleName}, toLang: $toLang, query: $query")
// FileLog.d("[Trans] use provider ${translator.javaClass.simpleName}, toLang: $toLang, query: $query")
return translator.doTranslate("auto", toLang, query)
}
@JvmStatic @JvmOverloads fun showTargetLangSelect(anchor: View, type: Int, full: Boolean = false, callback: (Locale) -> Unit) {
val builder = PopupBuilder(anchor)
var locales = (if (full) LocaleUtils.availableLocaleList() else LocaleController.getInstance().languages.map { it.pluralLangCode }.toSet().map { it.code2Locale }).filter { it.country.isBlank() && it.variant.isBlank() }.toTypedArray()
val currLocale = LocaleController.getInstance().currentLocale
for (i in locales.indices) {
val defLang = if (type < 2) currLocale else Locale.ENGLISH
if (locales[i] == defLang) {
locales = ArrayUtil.remove(locales, i)
locales = ArrayUtil.insert(locales, 0, defLang)
break
}
}
val localeNames = arrayOfNulls<String>(if (full) locales.size else locales.size + 1)
for (i in locales.indices) {
localeNames[i] = if (i == 0) {
LocaleController.getString("Default", R.string.Default) + " ( " + locales[i].getDisplayName(currLocale) + " )"
} else {
locales[i].getDisplayName(currLocale)
}
}
if (!full) {
localeNames[localeNames.size - 1] = LocaleController.getString("More", R.string.More)
}
val finalLocales = locales
builder.setItems(localeNames.filterIsInstance<CharSequence>().toTypedArray()) { index: Int, _ ->
if (index == locales.size) {
showTargetLangSelect(anchor, type, true, callback)
} else {
if (type == 1) {
NekoConfig.setTranslateToLang(finalLocales[index].locale2code)
} else if (type == 2) {
NekoConfig.setTranslateInputToLang(finalLocales[index].locale2code)
}
callback(locales[index])
}
}
builder.show()
}
@JvmStatic
@JvmOverloads
fun translate(to: Locale = LocaleController.getInstance().currentLocale, query: String, translateCallBack: TranslateCallBack) {

View File

@ -12,6 +12,7 @@ import tw.nekomimi.nekogram.transtale.TransUtils
import tw.nekomimi.nekogram.transtale.Translator
import tw.nekomimi.nekogram.utils.HttpUtil
import tw.nekomimi.nekogram.utils.applyUserAgent
import java.util.*
import java.util.regex.Pattern
object GoogleWebTranslator : Translator {

View File

@ -9,6 +9,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicLong
import java.util.concurrent.atomic.AtomicReference
import kotlin.collections.HashMap
import kotlin.reflect.KMutableProperty0
import kotlin.reflect.KProperty
import kotlin.reflect.KProperty0
@ -76,7 +77,7 @@ class WeakField<T> {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T {
return value
?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
}
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) {
@ -85,27 +86,42 @@ class WeakField<T> {
}
fun <T, R> receive(initializer: T.() -> R) = LazyReceiver(initializer)
fun <T, R> receive(getter: T.() -> R) = Receiver(getter)
class LazyReceiver<T, R>(val initializer: T.() -> R) {
private var isInitialized by AtomicBoolean()
private var _impl: R? = null
class Receiver<T, R>(val getter: T.() -> R) {
@Suppress("UNCHECKED_CAST")
operator fun getValue(thisRef: Any?, property: KProperty<*>): R {
if (isInitialized) return _impl as R
return getter(thisRef as T)
}
}
fun <T : Any, R> receiveLazy(initializer: T.() -> R) = LazyReceiver(initializer)
class LazyReceiver<T : Any, R>(val initializer: T.() -> R) {
private val isInitialized = HashMap<T, Unit>()
private val cache = HashMap<T, R>()
@Suppress("UNCHECKED_CAST")
operator fun getValue(thisRef: Any, property: KProperty<*>): R {
if (isInitialized[thisRef] != null) return cache[thisRef] as R
synchronized(this) {
if (isInitialized) return _impl as R
if (isInitialized[thisRef] != null) return cache[thisRef] as R
_impl = initializer(thisRef as T)
return initializer(thisRef as T).apply {
isInitialized = true
cache[thisRef] = this
return _impl as R
isInitialized[thisRef] = Unit
}
}

View File

@ -14,7 +14,6 @@
<string name="NekoXProxy">خادم NekoX العام</string>
<string name="DisableChatAction">لا تقم بإرسال حالة الإدخال</string>
<string name="FakeScreenshot">لقطة شاشة مخرجة</string>
<string name="SaveCacheToSdcard">حفظ التخزين المؤقت على sdcard*</string>
<string name="FilterNameUsers">المستخدمون</string>
<string name="FilterNameUsersDescription">فقط الرسائل من المحادثات الخاصة</string>
<string name="FilterNameContacts">جهات الاتصال</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">详情</string>
<string name="ExportAsJson">导出为 JSON</string>
<string name="Translate">翻译</string>
<string name="ServiceByGoogle">翻译服务由 Google 提供</string>
<string name="JoinedFormatted">加入于 %1$s</string>
<string name="JoinedDateFormatted">加入于 %1$s</string>
<string name="DeleteAccount">删除 Telegram 帐户</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google 中国翻译</string>
<string name="ProviderGoogleTranslateCNWeb">Google 中国翻译(网页)</string>
<string name="ProviderBaiduFanyiWeb">百度翻译(网页)</string>
<string name="TranslateApiUnsupported">您选择的翻译源不支持您的语言</string>
<string name="TranslateApiUnsupported">您选择的翻译源不支持您的语言.</string>
<string name="ProviderLingocloud">彩云小译</string>
<string name="UndoTranslate">撤销翻译</string>
<string name="CopyDetails">复制详细信息</string>
@ -84,7 +83,12 @@
<string name="CheckAllAdministrated">添加管理的群组与频道</string>
<string name="ProviderDeepLWeb">DeepL 翻译器(网页)</string>
<string name="ChatMessageAnimation">新消息动画</string>
<string name="RearVideoMessages">视频消息默认使用后置摄像头</string>
<string name="RearVideoMessages">视频留言默认使用后置摄像头</string>
<string name="HideAllTab">隐藏“全部对话”</string>
<string name="HideAllTabAbout">在主页按返回键打开全部对话</string>
<string name="HideAllTabAbout">在主页按返回键打开全部对话。</string>
<string name="TabTitleType">在标签栏上显示</string>
<string name="TabTitleTypeTip">图标由 Telegram 云同步。</string>
<string name="TabTitleTypeText">标题</string>
<string name="TabTitleTypeIcon">图标</string>
<string name="TabTitleTypeMix">图标与标题</string>
</resources>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="NekoSettings">Ajustes de Neko</string>
<string name="NekoSettings">Configuraciones de Neko</string>
<string name="IPv6">Intentar conectar a través de IPv6</string>
<string name="MessageMenu">Menú contextual</string>
<string name="HidePhone">Ocultar mi número de teléfono</string>
@ -56,7 +56,6 @@
<string name="MessageDetails">Detalles</string>
<string name="ExportAsJson">Exportar como JSON</string>
<string name="Translate">Traducir</string>
<string name="ServiceByGoogle">El servicio de traducción es provisto por Google</string>
<string name="JoinedFormatted">Se unió a las %1$s</string>
<string name="JoinedDateFormatted">Se unió el %1$s</string>
<string name="DeleteAccount">Eliminar cuenta de Telegram</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Traductor de Google CN</string>
<string name="ProviderGoogleTranslateCNWeb">Traductor de Google CN (Web)</string>
<string name="ProviderBaiduFanyiWeb">Traductor de Baidu (Web)</string>
<string name="TranslateApiUnsupported">El traductor escogido no soporta tu idioma</string>
<string name="TranslateApiUnsupported">El proveedor de traducción seleccionado no soporta su idioma.</string>
<string name="ProviderLingocloud">Lingocloud</string>
<string name="UndoTranslate">Deshacer traducción</string>
<string name="CopyDetails">Copiar Detalles</string>
@ -84,7 +83,12 @@
<string name="CheckAllAdministrated">Agregar administrador</string>
<string name="ProviderDeepLWeb">Traductor de DeepL (Web)</string>
<string name="ChatMessageAnimation">Animar los mensajes nuevos</string>
<string name="RearVideoMessages">Cámara trasera de Mensajes de Vídeo</string>
<string name="RearVideoMessages">Usar cámara trasera en Mensajes de Vídeo</string>
<string name="HideAllTab">Ocultar pestaña \"Todos los chats\"</string>
<string name="HideAllTabAbout">Presiona \"Atrás\" en la página de inicio para abrirlo</string>
<string name="HideAllTabAbout">Presiona \"Atrás\" en la página de inicio para abrirlo.</string>
<string name="TabTitleType">Mostrar en pestañas</string>
<string name="TabTitleTypeTip">Los emojis son sincronizados con la nube por Telegram.</string>
<string name="TabTitleTypeText">Títulos</string>
<string name="TabTitleTypeIcon">Emojis</string>
<string name="TabTitleTypeMix">Emojis con títulos</string>
</resources>

View File

@ -20,7 +20,6 @@
<string name="NekoXProxy">پروکسی عمومی NekoX</string>
<string name="DisableChatAction">وضعیت مرا ارسال نکن</string>
<string name="FakeScreenshot">تصویر پیش‌نمایش</string>
<string name="SaveCacheToSdcard">ذخیره کش در حافظه sd card</string>
<string name="FilterNameUsers">کاربران</string>
<string name="FilterNameUsersDescription">فقط پیام های چت های خصوصی</string>
<string name="FilterNameContacts">مخاطبین</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">Detail</string>
<string name="ExportAsJson">Ekspor sebagai JSON</string>
<string name="Translate">Terjemahan</string>
<string name="ServiceByGoogle">Layanan penerjemah disediakan oleh Google</string>
<string name="JoinedFormatted">bergabung %1$s</string>
<string name="JoinedDateFormatted">bergabung pada %1$s</string>
<string name="DeleteAccount">Hapus akun Telegram</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google Translate CN</string>
<string name="ProviderGoogleTranslateCNWeb">Google Translate CN (Web)</string>
<string name="ProviderBaiduFanyiWeb">Baidu Translate (Web)</string>
<string name="TranslateApiUnsupported">Penyedia terjemahan yang kamu pilih tidak mendukung bahasa anda</string>
<string name="TranslateApiUnsupported">Penyedia terjemahan yang kamu pilih tidak mendukung bahasa anda.</string>
<string name="ProviderLingocloud">Lingocloud</string>
<string name="UndoTranslate">Batalkan terjemahan</string>
<string name="CopyDetails">Salin detail</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">Dettagli</string>
<string name="ExportAsJson">Esporta come JSON</string>
<string name="Translate">Traduci</string>
<string name="ServiceByGoogle">Il servizio di traduzione è fornito da Google</string>
<string name="JoinedFormatted">entrato %1$s</string>
<string name="JoinedDateFormatted">entrato %1$s</string>
<string name="DeleteAccount">Elimina l\'account Telegram</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google Traduttore CN</string>
<string name="ProviderGoogleTranslateCNWeb">Google Traduttore CN (Web)</string>
<string name="ProviderBaiduFanyiWeb">Baidu Traduttore (Web)</string>
<string name="TranslateApiUnsupported">Il fornitore della traduzione selezionato non supporta la tua lingua</string>
<string name="TranslateApiUnsupported">Il fornitore della traduzione selezionato non supporta la tua lingua.</string>
<string name="ProviderLingocloud">Lingocloud</string>
<string name="UndoTranslate">Annulla traduzione</string>
<string name="CopyDetails">Copia Dettagli</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">詳細</string>
<string name="ExportAsJson">JSONとしてエクスポート</string>
<string name="Translate">翻訳</string>
<string name="ServiceByGoogle">翻訳サービスはGoogleによって提供されています</string>
<string name="DeleteAccount">Telegramアカウントの削除</string>
<string name="TranslateFailed">翻訳サーバエラー</string>
<string name="TranslationProvider">翻訳プロバイダ</string>
@ -65,7 +64,7 @@
<string name="ProviderGoogleTranslateCN">Google翻訳 CN</string>
<string name="ProviderGoogleTranslateCNWeb">Google翻訳 CN (Web)</string>
<string name="ProviderBaiduFanyiWeb">Baidu翻訳 (Web)</string>
<string name="TranslateApiUnsupported">選択した翻訳プロバイダはあなたの言語をサポートしていません</string>
<string name="TranslateApiUnsupported">選択した翻訳プロバイダはあなたの言語をサポートしていません.</string>
<string name="ProviderLingocloud">Lingocloud</string>
<string name="UndoTranslate">翻訳を取り消す</string>
<string name="CopyDetails">詳細のコピー</string>

View File

@ -14,7 +14,6 @@
<string name="NekoXProxy">NekoXパブリックプロキシ</string>
<string name="PublicPrefix">パブリック</string>
<string name="DisableChatAction">入力ステータスを送信しない</string>
<string name="SaveCacheToSdcard">キャッシュをSDカードに保存</string>
<string name="FilterNameUsers">ユーザー</string>
<string name="FilterNameUsersDescription">プライベートチャットからのメッセージのみ</string>
<string name="FilterNameContacts">連絡先</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">정보</string>
<string name="ExportAsJson">JSON으로 내보내기</string>
<string name="Translate">번역</string>
<string name="ServiceByGoogle">번역 서비스는 Google에서 제공합니다</string>
<string name="JoinedFormatted">%1$s 님 참여</string>
<string name="JoinedDateFormatted">%1$s 참여</string>
<string name="DeleteAccount">텔레그램 계정 삭제</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">구글 번역 CN</string>
<string name="ProviderGoogleTranslateCNWeb">구글 번역 CN (웹)</string>
<string name="ProviderBaiduFanyiWeb">바이두 번역 (웹)</string>
<string name="TranslateApiUnsupported">선택한 번역 공급자가 사용자의 언어를 지원하지 않습니다</string>
<string name="TranslateApiUnsupported">선택한 번역 공급자가 사용자의 언어를 지원하지 않습니다.</string>
<string name="ProviderLingocloud">링고 클라우드</string>
<string name="UndoTranslate">번역 취소</string>
<string name="CopyDetails">정보 복사</string>
@ -86,5 +85,5 @@
<string name="ChatMessageAnimation">새 애니메이션 메세지</string>
<string name="RearVideoMessages">비디오 메세지에 후면 카메라 사용</string>
<string name="HideAllTab">\"모든 채팅\" 탭 숨기기</string>
<string name="HideAllTabAbout">홈페이지의 \"뒤로\" 버튼 눌러서 열기</string>
<string name="HideAllTabAbout">홈페이지의 \"뒤로\" 버튼 눌러서 열기.</string>
</resources>

View File

@ -50,7 +50,6 @@
<string name="MessageDetails">Szczegóły</string>
<string name="ExportAsJson">Eksportuj jako JSON</string>
<string name="Translate">Przetłumacz</string>
<string name="ServiceByGoogle">Usługa tłumaczeniowa jest świadczona przez Google</string>
<string name="DeleteAccount">Usuń konto Telegram</string>
<string name="TranslationProvider">Dostawca tłumaczeń</string>
<string name="ProviderGoogleTranslate">Tłumacz Google</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">Detalhes</string>
<string name="ExportAsJson">Exportar como JSON</string>
<string name="Translate">Traduzir</string>
<string name="ServiceByGoogle">O serviço de tradução é fornecido pelo Google</string>
<string name="JoinedFormatted">visto por último %1$s</string>
<string name="JoinedDateFormatted">visto por último às %1$s</string>
<string name="DeleteAccount">Excluir conta do telegram</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google Tradutor CN</string>
<string name="ProviderGoogleTranslateCNWeb">Google Tradutor CN (Web)</string>
<string name="ProviderBaiduFanyiWeb">Baidu Tradutor (Web)</string>
<string name="TranslateApiUnsupported">O provedor de tradução que você selecionou não suporta o seu idioma</string>
<string name="TranslateApiUnsupported">O provedor de tradução que você selecionou não suporta o seu idioma.</string>
<string name="ProviderLingocloud">Lingocloud</string>
<string name="UndoTranslate">Desfazer tradução</string>
<string name="CopyDetails">Copiar Detalhes</string>
@ -86,5 +85,5 @@
<string name="ChatMessageAnimation">Animação de novas mensagens</string>
<string name="RearVideoMessages">Câmera traseira em mensagens de vídeo</string>
<string name="HideAllTab">Ocultar aba \"Todos os bate-papos\"</string>
<string name="HideAllTabAbout">Pressione o botão \"Voltar\" na página inicial, para abri-lo</string>
<string name="HideAllTabAbout">Pressione o botão \"Voltar\" na página inicial, para abri-lo.</string>
</resources>

View File

@ -15,7 +15,6 @@
<string name="PublicPrefix">Público</string>
<string name="DisableChatAction">Não enviar meu status de entrada</string>
<string name="FakeScreenshot">Simular captura de tela</string>
<string name="SaveCacheToSdcard">Salvar cache no cartão SD*</string>
<string name="FilterNameUsers">Usuários</string>
<string name="FilterNameUsersDescription">Apenas mensagens de conversas privadas</string>
<string name="FilterNameContacts">Contatos</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">Подробности</string>
<string name="ExportAsJson">Экспорт в JSON</string>
<string name="Translate">Перевод</string>
<string name="ServiceByGoogle">Служба перевода предоставлена Google</string>
<string name="JoinedFormatted">вступил в %1$s</string>
<string name="JoinedDateFormatted">вступил в %1$s</string>
<string name="DeleteAccount">Удалить Telegram аккаунт</string>
@ -67,7 +66,6 @@
<string name="ProviderGoogleTranslateCN">Google Переводчик CN</string>
<string name="ProviderGoogleTranslateCNWeb">Google Переводчик CN (Веб)</string>
<string name="ProviderBaiduFanyiWeb">Baido Переводчик (Веб)</string>
<string name="TranslateApiUnsupported">Поставщик переводов который вы выбрали не имеет поддержку Вашего языка</string>
<string name="ProviderLingocloud">Lingocloud</string>
<string name="UndoTranslate">Отменить перевод</string>
<string name="CopyDetails">Скопировать подробности</string>
@ -80,4 +78,11 @@
<string name="UserRestrictionsSendStickers2">Отправить стикеры</string>
<string name="UserRestrictionsSendGifs">Отправить GIF</string>
<string name="UseAvatarAsDrawerBackground">Использовать аватар в качестве фона меню</string>
<string name="ShowTabsOnForward">Показывать вкладки при пересылке</string>
<string name="CheckAllAdministrated">Добавить админские</string>
<string name="ProviderDeepLWeb">DeepL Переводчик (Веб)</string>
<string name="ChatMessageAnimation">Анимировать новые сообщения</string>
<string name="RearVideoMessages">Задняя камера в видео сообщениях</string>
<string name="HideAllTab">Скрыть \"Все чаты\" во вкладках</string>
<string name="HideAllTabAbout">Нажмите \"Назад\" на домашней странице, чтобы открыть.</string>
</resources>

View File

@ -27,7 +27,6 @@
<string name="PublicPrefix">Genel</string>
<string name="DisableChatAction">Giriş durumumu (yazıyor, vb.) gönderme</string>
<string name="FakeScreenshot">Ekran görüntüsü gibi davran</string>
<string name="SaveCacheToSdcard">Önbelleği SD Karta (Hafıza Kartına) Kaydet*</string>
<string name="Import">İçe aktar</string>
<string name="FilterNameUsers">Kullanıcılar</string>
<string name="FilterNameUsersDescription">Yalnızca özel sohbetlerden gelen iletiler</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">详情</string>
<string name="ExportAsJson">导出为 JSON</string>
<string name="Translate">翻译</string>
<string name="ServiceByGoogle">翻译服务由 Google 提供</string>
<string name="JoinedFormatted">加入于 %1$s</string>
<string name="JoinedDateFormatted">加入于 %1$s</string>
<string name="DeleteAccount">删除 Telegram 帐户</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google 中国翻译</string>
<string name="ProviderGoogleTranslateCNWeb">Google 中国翻译 (Web)</string>
<string name="ProviderBaiduFanyiWeb">百度翻译 (Web)</string>
<string name="TranslateApiUnsupported">您选择的翻译源不支持您的语言</string>
<string name="TranslateApiUnsupported">您选择的翻译源不支持您的语言</string>
<string name="ProviderLingocloud">彩云小译</string>
<string name="UndoTranslate">撤销翻译</string>
<string name="CopyDetails">复制详细信息</string>
@ -84,7 +83,12 @@
<string name="CheckAllAdministrated">添加管理的群组与频道</string>
<string name="ProviderDeepLWeb">DeepL 翻译器(网页)</string>
<string name="ChatMessageAnimation">新消息动画</string>
<string name="RearVideoMessages">视频消息默认使用后置摄像头</string>
<string name="RearVideoMessages">视频留言默认使用后置摄像头</string>
<string name="HideAllTab">隐藏“全部对话”</string>
<string name="HideAllTabAbout">在主页按返回键打开全部对话</string>
<string name="HideAllTabAbout">在主页按返回键打开全部对话。</string>
<string name="TabTitleType">在标签上显示</string>
<string name="TabTitleTypeTip">图标由 Telegram 云同步。</string>
<string name="TabTitleTypeText">标题</string>
<string name="TabTitleTypeIcon">图标</string>
<string name="TabTitleTypeMix">图标与标题</string>
</resources>

View File

@ -37,7 +37,6 @@
<string name="PublicPrefix">公共</string>
<string name="DisableChatAction">不要发送我的输入状态</string>
<string name="FakeScreenshot">假装截屏</string>
<string name="SaveCacheToSdcard">保存缓存到内部存储*</string>
<string name="Import">导入</string>
<string name="FilterNameUsers">用户</string>
<string name="FilterNameUsersDescription">仅来自私聊的消息</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">資訊</string>
<string name="ExportAsJson">導出為 JSON</string>
<string name="Translate">翻譯</string>
<string name="ServiceByGoogle">翻譯服務由 Google 提供</string>
<string name="JoinedFormatted">加入於 %1$s</string>
<string name="JoinedDateFormatted">加入於 %1$s</string>
<string name="DeleteAccount">刪除 Telegram 帳戶</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google 中國翻譯</string>
<string name="ProviderGoogleTranslateCNWeb">Google 中國翻譯 (Web)</string>
<string name="ProviderBaiduFanyiWeb">百度翻譯 (Web)</string>
<string name="TranslateApiUnsupported">您選擇的翻譯源不支持您的語言</string>
<string name="TranslateApiUnsupported">您選擇的翻譯源不支持您的語言.</string>
<string name="ProviderLingocloud">彩雲小譯</string>
<string name="UndoTranslate">撤銷翻譯</string>
<string name="CopyDetails">複製詳細資訊</string>

View File

@ -27,7 +27,6 @@
<string name="PublicPrefix">公共</string>
<string name="DisableChatAction">不要發送我的輸入狀態</string>
<string name="FakeScreenshot">假裝截屏</string>
<string name="SaveCacheToSdcard">保存緩存到存儲卡*</string>
<string name="Import">導入</string>
<string name="FilterNameUsers">用戶</string>
<string name="FilterNameUsersDescription">僅來自私聊的消息</string>

View File

@ -56,7 +56,6 @@
<string name="MessageDetails">資訊</string>
<string name="ExportAsJson">匯出為 JSON</string>
<string name="Translate">翻譯</string>
<string name="ServiceByGoogle">翻譯服務由 Google 提供</string>
<string name="JoinedFormatted">加入於 %1$s</string>
<string name="JoinedDateFormatted">加入於 %1$s</string>
<string name="DeleteAccount">刪除 Telegram 帳戶</string>
@ -67,7 +66,7 @@
<string name="ProviderGoogleTranslateCN">Google 中國翻譯</string>
<string name="ProviderGoogleTranslateCNWeb">Google 中國翻譯 (網頁版)</string>
<string name="ProviderBaiduFanyiWeb">百度翻譯 (網頁版)</string>
<string name="TranslateApiUnsupported">您選擇的翻譯來源不支援您的語言</string>
<string name="TranslateApiUnsupported">您選擇的翻譯來源不支援您的語言.</string>
<string name="ProviderLingocloud">彩雲小譯</string>
<string name="UndoTranslate">撤銷翻譯</string>
<string name="CopyDetails">複製詳細資訊</string>
@ -80,4 +79,11 @@
<string name="UserRestrictionsSendStickers2">傳送貼圖</string>
<string name="UserRestrictionsSendGifs">發送動圖</string>
<string name="UseAvatarAsDrawerBackground">使用頭像作為程式集背景</string>
<string name="ShowTabsOnForward">在轉傳的頁面中顯示標籤</string>
<string name="CheckAllAdministrated">新增管理員</string>
<string name="ProviderDeepLWeb">DeepL 翻譯器 (web)</string>
<string name="ChatMessageAnimation">新消息動畫</string>
<string name="RearVideoMessages">視頻消息中使用後置攝像頭</string>
<string name="HideAllTab">隱藏“所有聊天”標籤</string>
<string name="HideAllTabAbout">在主頁上按“返回”以將其打開.</string>
</resources>

View File

@ -27,7 +27,6 @@
<string name="PublicPrefix">公共</string>
<string name="DisableChatAction">不要發送我的輸入狀態</string>
<string name="FakeScreenshot">假裝截屏</string>
<string name="SaveCacheToSdcard">保存緩存到存儲卡*</string>
<string name="Import">導入</string>
<string name="FilterNameUsers">用戶</string>
<string name="FilterNameUsersDescription">僅來自私聊的消息</string>

View File

@ -8,6 +8,7 @@
<item name="menu_strike" type="id"/>
<item name="menu_underline" type="id"/>
<item name="menu_groupbolditalic" type="id"/>
<item name="menu_translate" type="id" />
<item name="parent_tag" type="id"/>
<item name="object_tag" type="id"/>
<item name="index_tag" type="id"/>

View File

@ -29,6 +29,10 @@
<string name="GoogleCloudTransKey">Google Cloud Translate Key</string>
<string name="GoogleCloudTransKeyNotice">If you set up a Google Cloud Trans Key, the cloud translation API will be called instead of submitting a fake form to the web version when translating (faster, stable and saving traffic).</string>
<string name="TransToLang">Translation target language</string>
<string name="TransInputToLang">Translation input target language</string>
<string name="More">More</string>
<string name="NekoXUpdatesChannel">NekoX Updates Channel</string>
<string name="ShowIdAndDc">Show ID / DC in profile</string>
<string name="UseDefaultTheme">Use default theme *</string>
@ -52,7 +56,6 @@
<string name="DisableChatAction">Don\'t send my input status</string>
<string name="FakeScreenshot">Pretend screenshot</string>
<string name="SaveCacheToSdcard">Save cache to sdcard*</string>
<string name="Import">Import</string>