Support poll translation

This commit is contained in:
NekoInverter 2020-06-09 22:26:55 +08:00
parent 3ffd66bf0d
commit 28df060626
No known key found for this signature in database
GPG Key ID: 280D6CCCF95715F9
8 changed files with 235 additions and 207 deletions

View File

@ -131,6 +131,9 @@ public class MessageObject {
public boolean scheduled;
public boolean translated;
public Object originalMessage;
public ArrayList<TLRPC.TL_pollAnswer> checkedVotes;
public CharSequence editingMessage;

View File

@ -14860,9 +14860,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
options.add(89);
icons.add(R.drawable.menu_info);
}
if (!TextUtils.isEmpty(selectedObject.messageOwner.message) && NekoConfig.showTranslate) {
Matcher matcher = Pattern.compile("\u200C\u200C\\n\\n--------\\n.*\u200C\u200C", Pattern.DOTALL).matcher(selectedObject.messageOwner.message);
items.add(matcher.find() ? LocaleController.getString("UndoTranslate", R.string.UndoTranslate) : LocaleController.getString("Translate", R.string.Translate));
if ((!TextUtils.isEmpty(selectedObject.messageOwner.message) || selectedObject.type == MessageObject.TYPE_POLL) && NekoConfig.showTranslate) {
items.add(selectedObject.translated ? LocaleController.getString("UndoTranslate", R.string.UndoTranslate) : LocaleController.getString("Translate", R.string.Translate));
options.add(88);
icons.add(R.drawable.ic_translate);
}
@ -15880,7 +15879,20 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
break;
} case 88: {
if (NekoConfig.translationProvider < 0) {
if (selectedObject.type == MessageObject.TYPE_POLL) {
TLRPC.Poll poll = ((TLRPC.TL_messageMediaPoll) selectedObject.messageOwner.media).poll;
StringBuilder sb = new StringBuilder();
sb.append(poll.question);
sb.append("\n");
sb.append("--------");
for (TLRPC.TL_pollAnswer answer: poll.answers) {
sb.append("\n");
sb.append(answer.text);
}
TranslateBottomSheet.show(getParentActivity(), sb.toString());
} else {
TranslateBottomSheet.show(getParentActivity(), selectedObject.messageOwner.message);
}
} else {
ChatMessageCell messageCell = null;
int count = chatListView.getChildCount();
@ -15894,38 +15906,53 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
}
String original = selectedObject.messageOwner.message;
Matcher matcher = Pattern.compile("\u200C\u200C\\n\\n--------\\n.*\u200C\u200C", Pattern.DOTALL).matcher(original);
if (matcher.find()){
if (messageCell != null) {
MessageHelper.setMessageContent(selectedObject,messageCell,original.replace(matcher.group(),""));
if (selectedObject.translated){
if (messageCell != null && selectedObject.originalMessage != null) {
if (selectedObject.originalMessage instanceof String) {
selectedObject.messageOwner.message = (String) selectedObject.originalMessage;
} else if (selectedObject.originalMessage instanceof TLRPC.TL_poll) {
((TLRPC.TL_messageMediaPoll) selectedObject.messageOwner.media).poll = (TLRPC.TL_poll) selectedObject.originalMessage;
}
MessageHelper.resetMessageContent(selectedObject, messageCell);
chatAdapter.updateRowWithMessageObject(selectedObject, true);
selectedObject.translated = false;
}
} else {
Object original = selectedObject.type == MessageObject.TYPE_POLL ? ((TLRPC.TL_messageMediaPoll) selectedObject.messageOwner.media).poll : selectedObject.messageOwner.message;
selectedObject.originalMessage = original;
ChatMessageCell finalMessageCell = messageCell;
int finalOption = option;
Translator.translate(original, new Translator.TranslateCallBack() {
@Override
public void onSuccess(String translation) {
public void onSuccess(Object translation) {
if (finalMessageCell != null) {
MessageObject messageObject = finalMessageCell.getMessageObject();
MessageHelper.setMessageContent(messageObject,finalMessageCell,original +
"\u200C\u200C\n" +
if (translation instanceof String) {
messageObject.messageOwner.message = original +
"\n" +
"--------" +
"\n" +
translation +
"\u200C\u200C");
translation;
} else if (translation instanceof TLRPC.TL_poll) {
((TLRPC.TL_messageMediaPoll) messageObject.messageOwner.media).poll = (TLRPC.TL_poll) translation;
}
MessageHelper.resetMessageContent(messageObject, finalMessageCell);
chatAdapter.updateRowWithMessageObject(messageObject, true);
messageObject.translated = true;
}
}
@Override
public void onError() {
public void onError(Throwable e) {
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
if (e != null && e.getLocalizedMessage() != null) {
builder.setTitle(LocaleController.getString("TranslateFailed", R.string.TranslateFailed));
builder.setMessage(e.getLocalizedMessage());
} else {
builder.setMessage(LocaleController.getString("TranslateFailed", R.string.TranslateFailed));
}
builder.setNeutralButton(LocaleController.getString("TranslationProvider", R.string.TranslationProvider), (dialog, which) -> showDialog(NekoGeneralSettingsActivity.getTranslationProviderAlert(getParentActivity())));
builder.setPositiveButton(LocaleController.getString("Retry", R.string.Retry), (dialog, which) -> processSelectedOption(option));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
showDialog(builder.create());
}

View File

@ -31,12 +31,11 @@ public class MessageHelper extends BaseController {
super(num);
}
public static void setMessageContent(MessageObject messageObject, ChatMessageCell chatMessageCell, String message) {
messageObject.messageOwner.message = message;
public static void resetMessageContent(MessageObject messageObject, ChatMessageCell chatMessageCell) {
messageObject.forceUpdate = true;
if (messageObject.caption != null) {
messageObject.caption = null;
messageObject.generateCaption();
messageObject.forceUpdate = true;
}
messageObject.applyNewText();
messageObject.resetLayout();
@ -55,24 +54,29 @@ public class MessageHelper extends BaseController {
progressDialog.showDelayed(400);
Translator.translate(query, new Translator.TranslateCallBack() {
@Override
public void onSuccess(String translation) {
public void onSuccess(Object translation) {
if (progressDialog != null) {
progressDialog.dismiss();
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(translation);
builder.setMessage((String) translation);
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.setNeutralButton(LocaleController.getString("Copy", R.string.Copy), (dialog, which) -> AndroidUtilities.addToClipboard(translation));
builder.setNeutralButton(LocaleController.getString("Copy", R.string.Copy), (dialog, which) -> AndroidUtilities.addToClipboard((String) translation));
builder.show();
}
@Override
public void onError() {
public void onError(Throwable e) {
if (progressDialog != null) {
progressDialog.dismiss();
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
if (e != null && e.getLocalizedMessage() != null) {
builder.setTitle(LocaleController.getString("TranslateFailed", R.string.TranslateFailed));
builder.setMessage(e.getLocalizedMessage());
} else {
builder.setMessage(LocaleController.getString("TranslateFailed", R.string.TranslateFailed));
}
builder.setNeutralButton(LocaleController.getString("TranslationProvider", R.string.TranslationProvider), (dialog, which) -> NekoGeneralSettingsActivity.getTranslationProviderAlert(context).show());
builder.setPositiveButton(LocaleController.getString("Retry", R.string.Retry), (dialog, which) -> showTranslateDialog(context, query));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);

View File

@ -320,9 +320,7 @@ public class NekoGeneralSettingsActivity extends BaseFragment {
}
restartTooltip.showWithAction(0, UndoView.ACTION_CACHE_WAS_CLEARED, null, null);
} else if (position == translationProviderRow) {
AlertDialog dialog = getTranslationProviderAlert(context);
dialog.setOnDismissListener(dialog1 -> listAdapter.notifyItemChanged(translationProviderRow));
showDialog(dialog);
showDialog(getTranslationProviderAlert(context)).setOnDismissListener(dialog1 -> listAdapter.notifyItemChanged(translationProviderRow));
} else if (position == openArchiveOnPullRow) {
NekoConfig.toggleOpenArchiveOnPull();
if (view instanceof TextCheckCell) {

View File

@ -8,6 +8,7 @@ import org.json.JSONTokener;
import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
@ -44,7 +45,7 @@ public class GoogleWebTranslator extends Translator {
}
@Override
protected String translate(String query, String tl) {
protected String translate(String query, String tl) throws IOException {
String result = translateImpl(query, tl);
if (result == null) {
tkk = null;
@ -59,7 +60,7 @@ public class GoogleWebTranslator extends Translator {
}
private String translateImpl(String query, String tl) {
private String translateImpl(String query, String tl) throws IOException {
if (tkk == null) {
initTkk();
}
@ -92,7 +93,7 @@ public class GoogleWebTranslator extends Translator {
return sb.toString();
}
private void initTkk() {
private void initTkk() throws IOException {
String response = request("https://translate.google." + (NekoConfig.translationProvider == PROVIDER_GOOGLE_CN ? "cn" : "com"));
if (TextUtils.isEmpty(response)) {
FileLog.e("Tkk init failed");
@ -117,8 +118,7 @@ public class GoogleWebTranslator extends Translator {
return null;
}
private String request(String url) {
try {
private String request(String url) throws IOException {
ByteArrayOutputStream outbuf;
InputStream httpConnectionStream;
URL downloadUrl = new URL(url);
@ -142,21 +142,10 @@ public class GoogleWebTranslator extends Translator {
break;
}
}
String result = new String(outbuf.toByteArray());
try {
httpConnectionStream.close();
} catch (Throwable e) {
FileLog.e(e);
}
try {
outbuf.close();
} catch (Exception ignore) {
}
String result = new String(outbuf.toByteArray());
httpConnectionStream.close();
outbuf.close();
return result;
} catch (Throwable e) {
FileLog.e(e);
return null;
}
}
}

View File

@ -12,6 +12,7 @@ import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
@ -40,28 +41,22 @@ public class LingoTranslator extends Translator {
}
@Override
protected String translate(String query, String tl) {
protected String translate(String query, String tl) throws IOException {
LingoRequest params = new LingoRequest(query, "auto2" + tl);
Gson gson = new Gson();
String response = request(gson.toJson(params));
if (TextUtils.isEmpty(response)) {
return null;
}
try {
LingoResponse lingoResponse = gson.fromJson(response, LingoResponse.class);
if (TextUtils.isEmpty(lingoResponse.target)) {
FileLog.e(response);
return null;
}
return lingoResponse.target;
} catch (Exception e) {
FileLog.e(response + e);
return null;
}
}
private String request(String param) {
try {
private String request(String param) throws IOException {
ByteArrayOutputStream outbuf;
InputStream httpConnectionStream;
URL downloadUrl = new URL("https://api.interpreter.caiyunai.com/v1/translator");
@ -99,21 +94,9 @@ public class LingoTranslator extends Translator {
}
}
String result = new String(outbuf.toByteArray());
try {
httpConnectionStream.close();
} catch (Throwable e) {
FileLog.e(e);
}
try {
outbuf.close();
} catch (Exception ignore) {
}
return result;
} catch (Throwable e) {
FileLog.e(e);
return null;
}
}
public static class LingoRequest {

View File

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

View File

@ -7,8 +7,8 @@ import org.telegram.messenger.FileLog;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
@ -54,7 +54,7 @@ public class YandexTranslator extends Translator {
}
@Override
protected String translate(String query, String tl) {
protected String translate(String query, String tl) throws IOException, JSONException {
String result = translateImpl(query, tl);
if (result == null) {
return translateImpl(query, tl);
@ -67,23 +67,15 @@ public class YandexTranslator extends Translator {
return targetLanguages;
}
private String translateImpl(String query, String tl) {
private String translateImpl(String query, String tl) throws IOException, JSONException {
String url = "https://translate.yandex.net/api/v1.5/tr.json/translate"
+ "?key=trnsl.1.1.20160205T121943Z.0208eaff12c2747d.9526187390798b3098ec23e8f02073168e0b52c1"
+ "&lang=" + tl;
try {
return getResult(request(url, "text=" + URLEncoder.encode(query, "UTF-8")));
} catch (JSONException e) {
e.printStackTrace();
return null;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
private String request(String url, String param) {
try {
private String request(String url, String param) throws IOException {
ByteArrayOutputStream outbuf;
InputStream httpConnectionStream;
URL downloadUrl = new URL(url);
@ -131,9 +123,6 @@ public class YandexTranslator extends Translator {
}
return result;
} catch (Throwable e) {
FileLog.e(e);
return null;
}
}
}