From 4be595ea54425ebf08ca6538827e08cf4cdc6b58 Mon Sep 17 00:00:00 2001 From: Thomas Date: Tue, 27 Dec 2022 16:50:08 +0100 Subject: [PATCH] Add deepl support --- .../android/activities/MediaActivity.java | 94 ++++--------------- .../app/fedilab/android/helper/Helper.java | 6 +- .../android/helper/TranslateHelper.java | 91 ++++++++++++++++++ .../android/ui/drawer/ReleaseNoteAdapter.java | 46 ++------- .../android/ui/drawer/StatusAdapter.java | 45 ++------- .../settings/FragmentTimelinesSettings.java | 27 +++++- app/src/main/res/values/strings.xml | 31 ++++++ app/src/main/res/xml/pref_timelines.xml | 26 +++++ .../stom79/mytransl/translate/Helper.java | 10 +- .../stom79/mytransl/translate/Params.java | 10 ++ .../metadata/android/en/changelogs/455.txt | 7 ++ 11 files changed, 237 insertions(+), 156 deletions(-) create mode 100644 app/src/main/java/app/fedilab/android/helper/TranslateHelper.java create mode 100644 src/fdroid/fastlane/metadata/android/en/changelogs/455.txt diff --git a/app/src/main/java/app/fedilab/android/activities/MediaActivity.java b/app/src/main/java/app/fedilab/android/activities/MediaActivity.java index 608f6f35..a93697f6 100644 --- a/app/src/main/java/app/fedilab/android/activities/MediaActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/MediaActivity.java @@ -21,14 +21,12 @@ import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; -import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.graphics.Point; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; -import android.text.Html; import android.view.Display; import android.view.Menu; import android.view.MenuItem; @@ -44,15 +42,8 @@ import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentStatePagerAdapter; -import androidx.preference.PreferenceManager; import androidx.viewpager.widget.ViewPager; -import com.github.stom79.mytransl.MyTransL; -import com.github.stom79.mytransl.client.HttpsConnectionException; -import com.github.stom79.mytransl.client.Results; -import com.github.stom79.mytransl.translate.Params; -import com.github.stom79.mytransl.translate.Translate; - import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -63,6 +54,7 @@ import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.databinding.ActivityMediaPagerBinding; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.MediaHelper; +import app.fedilab.android.helper.TranslateHelper; import app.fedilab.android.interfaces.OnDownloadInterface; import app.fedilab.android.ui.fragment.media.FragmentMedia; import es.dmoral.toasty.Toasty; @@ -157,40 +149,14 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload binding.mediaDescription.setText(description); binding.translate.setOnClickListener(v -> { String descriptionToTranslate = attachments.get(mediaPosition - 1).description; - MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE; - final MyTransL myTransL = MyTransL.getInstance(et); - myTransL.setObfuscation(true); - Params params = new Params(); - params.setSplit_sentences(false); - params.setFormat(Params.fType.TEXT); - params.setSource_lang("auto"); - myTransL.setLibretranslateDomain("translate.fedilab.app"); - String statusToTranslate; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - statusToTranslate = Html.fromHtml(descriptionToTranslate, Html.FROM_HTML_MODE_LEGACY).toString(); - else - statusToTranslate = Html.fromHtml(descriptionToTranslate).toString(); - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(MediaActivity.this); - String translate = sharedpreferences.getString(getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale()); - if (translate != null && translate.equalsIgnoreCase("default")) { - translate = MyTransL.getLocale(); - } - myTransL.translate(statusToTranslate, translate, params, new Results() { - @Override - public void onSuccess(Translate translate) { - if (translate.getTranslatedContent() != null) { - attachments.get(mediaPosition - 1).translation = translate.getTranslatedContent(); - binding.mediaDescriptionTranslated.setText(translate.getTranslatedContent()); - binding.mediaDescriptionTranslated.setVisibility(View.VISIBLE); - binding.mediaDescription.setVisibility(View.GONE); - } else { - Toasty.error(MediaActivity.this, getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); - } - } - - @Override - public void onFail(HttpsConnectionException httpsConnectionException) { - + TranslateHelper.translate(MediaActivity.this, descriptionToTranslate, translated -> { + if (translated != null) { + attachments.get(mediaPosition - 1).translation = translated; + binding.mediaDescriptionTranslated.setText(translated); + binding.mediaDescriptionTranslated.setVisibility(View.VISIBLE); + binding.mediaDescription.setVisibility(View.GONE); + } else { + Toasty.error(MediaActivity.this, getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); } }); }); @@ -222,40 +188,14 @@ public class MediaActivity extends BaseTransparentActivity implements OnDownload } binding.translate.setOnClickListener(v -> { String descriptionToTranslate = attachments.get(position).description; - MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE; - final MyTransL myTransL = MyTransL.getInstance(et); - myTransL.setObfuscation(true); - Params params = new Params(); - params.setSplit_sentences(false); - params.setFormat(Params.fType.TEXT); - params.setSource_lang("auto"); - myTransL.setLibretranslateDomain("translate.fedilab.app"); - String statusToTranslate; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) - statusToTranslate = Html.fromHtml(descriptionToTranslate, Html.FROM_HTML_MODE_LEGACY).toString(); - else - statusToTranslate = Html.fromHtml(descriptionToTranslate).toString(); - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(MediaActivity.this); - String translate = sharedpreferences.getString(getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale()); - if (translate != null && translate.equalsIgnoreCase("default")) { - translate = MyTransL.getLocale(); - } - myTransL.translate(statusToTranslate, translate, params, new Results() { - @Override - public void onSuccess(Translate translate) { - if (translate.getTranslatedContent() != null) { - attachments.get(position).translation = translate.getTranslatedContent(); - binding.mediaDescriptionTranslated.setText(translate.getTranslatedContent()); - binding.mediaDescriptionTranslated.setVisibility(View.VISIBLE); - binding.mediaDescription.setVisibility(View.GONE); - } else { - Toasty.error(MediaActivity.this, getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); - } - } - - @Override - public void onFail(HttpsConnectionException httpsConnectionException) { - + TranslateHelper.translate(MediaActivity.this, descriptionToTranslate, translated -> { + if (translated != null) { + attachments.get(position).translation = translated; + binding.mediaDescriptionTranslated.setText(translated); + binding.mediaDescriptionTranslated.setVisibility(View.VISIBLE); + binding.mediaDescription.setVisibility(View.GONE); + } else { + Toasty.error(MediaActivity.this, getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); } }); }); diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index 75ea7626..dc415779 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -124,14 +124,17 @@ import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Date; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Random; +import java.util.Set; import java.util.TimeZone; import java.util.UUID; import java.util.regex.Matcher; @@ -1236,7 +1239,8 @@ public class Helper { counter++; Date now = new Date(); attachment.filename = formatter.format(now) + "." + extension; - if (attachment.mimeType.startsWith("image")) { + Set imageType = new HashSet<>(Arrays.asList("image/png", "image/jpeg", "image/jpg")); + if (imageType.contains(attachment.mimeType)) { final File certCacheDir = new File(context.getCacheDir(), TEMP_MEDIA_DIRECTORY); boolean isCertCacheDirExists = certCacheDir.exists(); if (!isCertCacheDirExists) { diff --git a/app/src/main/java/app/fedilab/android/helper/TranslateHelper.java b/app/src/main/java/app/fedilab/android/helper/TranslateHelper.java new file mode 100644 index 00000000..2edbb8ac --- /dev/null +++ b/app/src/main/java/app/fedilab/android/helper/TranslateHelper.java @@ -0,0 +1,91 @@ +package app.fedilab.android.helper; +/* Copyright 2022 Thomas Schneider + * + * This file is a part of Fedilab + * + * This program is free software; you can redistribute it and/or modify it under the terms of the + * GNU General Public License as published by the Free Software Foundation; either version 3 of the + * License, or (at your option) any later version. + * + * Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + * Public License for more details. + * + * You should have received a copy of the GNU General Public License along with Fedilab; if not, + * see . */ + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Build; +import android.text.Html; +import android.widget.Toast; + +import androidx.preference.PreferenceManager; + +import com.github.stom79.mytransl.MyTransL; +import com.github.stom79.mytransl.client.HttpsConnectionException; +import com.github.stom79.mytransl.client.Results; +import com.github.stom79.mytransl.translate.Params; + +import app.fedilab.android.R; +import es.dmoral.toasty.Toasty; + +public class TranslateHelper { + + public static void translate(Context context, String toTranslate, Translate callback) { + String statusToTranslate; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) + statusToTranslate = Html.fromHtml(toTranslate, Html.FROM_HTML_MODE_LEGACY).toString(); + else + statusToTranslate = Html.fromHtml(toTranslate).toString(); + SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); + String translator = sharedpreferences.getString(context.getString(R.string.SET_TRANSLATOR), "FEDILAB"); + MyTransL.translatorEngine et; + if (translator.compareToIgnoreCase("FEDILAB") == 0) { + et = MyTransL.translatorEngine.LIBRETRANSLATE; + } else { + et = MyTransL.translatorEngine.DEEPL; + } + final MyTransL myTransL = MyTransL.getInstance(et); + myTransL.setObfuscation(true); + Params params = new Params(); + params.setSplit_sentences(false); + params.setFormat(Params.fType.TEXT); + params.setSource_lang("auto"); + if (translator.compareToIgnoreCase("FEDILAB") == 0) { + myTransL.setLibretranslateDomain("translate.fedilab.app"); + } else { + String translatorVersion = sharedpreferences.getString(context.getString(R.string.SET_TRANSLATOR_VERSION), "PRO"); + params.setPro(translatorVersion.equals("PRO")); + String apikey = sharedpreferences.getString(context.getString(R.string.SET_TRANSLATOR_API_KEY), null); + myTransL.setDeeplAPIKey(apikey.trim()); + } + + String translate = sharedpreferences.getString(context.getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale()); + if (translate.equalsIgnoreCase("default")) { + translate = MyTransL.getLocale(); + } + + myTransL.translate(statusToTranslate, translate, params, new Results() { + @Override + public void onSuccess(com.github.stom79.mytransl.translate.Translate translate) { + if (translate.getTranslatedContent() != null) { + callback.onTranslate(translate.getTranslatedContent()); + } else { + callback.onTranslate(""); + Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onFail(HttpsConnectionException httpsConnectionException) { + callback.onTranslate(""); + Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); + } + }); + } + + public interface Translate { + void onTranslate(String translated); + } +} diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java index 6e4309ca..65353d33 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/ReleaseNoteAdapter.java @@ -16,28 +16,21 @@ package app.fedilab.android.ui.drawer; import android.content.Context; -import android.content.SharedPreferences; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.preference.PreferenceManager; import androidx.recyclerview.widget.RecyclerView; -import com.github.stom79.mytransl.MyTransL; -import com.github.stom79.mytransl.client.HttpsConnectionException; -import com.github.stom79.mytransl.client.Results; -import com.github.stom79.mytransl.translate.Params; -import com.github.stom79.mytransl.translate.Translate; - import java.util.List; import java.util.Locale; import app.fedilab.android.R; import app.fedilab.android.client.entities.app.ReleaseNote; import app.fedilab.android.databinding.DrawerReleaseNoteBinding; +import app.fedilab.android.helper.TranslateHelper; import es.dmoral.toasty.Toasty; @@ -81,37 +74,14 @@ public class ReleaseNoteAdapter extends RecyclerView.Adapter { - MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE; - final MyTransL myTransL = MyTransL.getInstance(et); - myTransL.setObfuscation(true); - Params params = new Params(); - params.setSplit_sentences(false); - params.setFormat(Params.fType.TEXT); - params.setSource_lang("auto"); - myTransL.setLibretranslateDomain("translate.fedilab.app"); - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - String translate = sharedpreferences.getString(context.getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale()); - if (translate != null && translate.equalsIgnoreCase("default")) { - translate = MyTransL.getLocale(); + holder.binding.translate.setOnClickListener(v -> TranslateHelper.translate(context, note.note, translated -> { + if (translated != null) { + note.noteTranslated = translated; + notifyItemChanged(holder.getBindingAdapterPosition()); + } else { + Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); } - myTransL.translate(note.note, translate, params, new Results() { - @Override - public void onSuccess(Translate translate) { - if (translate.getTranslatedContent() != null) { - note.noteTranslated = translate.getTranslatedContent(); - notifyItemChanged(holder.getBindingAdapterPosition()); - } else { - Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); - } - } - - @Override - public void onFail(HttpsConnectionException httpsConnectionException) { - Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); - } - }); - }); + })); } diff --git a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java index a2f6013f..f0be81cc 100644 --- a/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +++ b/app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java @@ -87,10 +87,6 @@ import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestOptions; import com.github.stom79.mytransl.MyTransL; -import com.github.stom79.mytransl.client.HttpsConnectionException; -import com.github.stom79.mytransl.client.Results; -import com.github.stom79.mytransl.translate.Params; -import com.github.stom79.mytransl.translate.Translate; import com.vanniktech.emoji.EmojiManager; import com.vanniktech.emoji.EmojiPopup; import com.vanniktech.emoji.one.EmojiOneProvider; @@ -145,6 +141,7 @@ import app.fedilab.android.helper.MediaHelper; import app.fedilab.android.helper.SpannableHelper; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.helper.TimelineHelper; +import app.fedilab.android.helper.TranslateHelper; import app.fedilab.android.ui.fragment.timeline.FragmentMastodonContext; import app.fedilab.android.viewmodel.mastodon.AccountsVM; import app.fedilab.android.viewmodel.mastodon.SearchVM; @@ -1982,6 +1979,7 @@ public class StatusAdapter extends RecyclerView.Adapter } + private static void translate(Context context, Status statusToDeal, StatusViewHolder holder, RecyclerView.Adapter adapter) { @@ -1990,40 +1988,15 @@ public class StatusAdapter extends RecyclerView.Adapter statusToTranslate = Html.fromHtml(statusToDeal.content, Html.FROM_HTML_MODE_LEGACY).toString(); else statusToTranslate = Html.fromHtml(statusToDeal.content).toString(); - int countMorseChar = ComposeAdapter.countMorseChar(statusToTranslate); if (countMorseChar < 4) { - MyTransL.translatorEngine et = MyTransL.translatorEngine.LIBRETRANSLATE; - final MyTransL myTransL = MyTransL.getInstance(et); - myTransL.setObfuscation(true); - Params params = new Params(); - params.setSplit_sentences(false); - params.setFormat(Params.fType.TEXT); - params.setSource_lang("auto"); - myTransL.setLibretranslateDomain("translate.fedilab.app"); - - SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); - String translate = sharedpreferences.getString(context.getString(R.string.SET_LIVE_TRANSLATE), MyTransL.getLocale()); - if (translate != null && translate.equalsIgnoreCase("default")) { - translate = MyTransL.getLocale(); - } - - - myTransL.translate(statusToTranslate, translate, params, new Results() { - @Override - public void onSuccess(Translate translate) { - if (translate.getTranslatedContent() != null) { - statusToDeal.translationShown = true; - statusToDeal.translationContent = translate.getTranslatedContent(); - adapter.notifyItemChanged(holder.getBindingAdapterPosition()); - } else { - Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); - } - } - - @Override - public void onFail(HttpsConnectionException httpsConnectionException) { - + TranslateHelper.translate(context, statusToDeal.content, translated -> { + if (translated != null) { + statusToDeal.translationShown = true; + statusToDeal.translationContent = translated; + adapter.notifyItemChanged(holder.getBindingAdapterPosition()); + } else { + Toasty.error(context, context.getString(R.string.toast_error_translate), Toast.LENGTH_LONG).show(); } }); } else { diff --git a/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentTimelinesSettings.java b/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentTimelinesSettings.java index a8f2a5ee..04fd9e9f 100644 --- a/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentTimelinesSettings.java +++ b/app/src/main/java/app/fedilab/android/ui/fragment/settings/FragmentTimelinesSettings.java @@ -17,9 +17,11 @@ package app.fedilab.android.ui.fragment.settings; import android.content.SharedPreferences; import android.os.Bundle; +import androidx.preference.EditTextPreference; import androidx.preference.ListPreference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceManager; +import androidx.preference.PreferenceScreen; import app.fedilab.android.R; import app.fedilab.android.helper.Helper; @@ -33,10 +35,31 @@ public class FragmentTimelinesSettings extends PreferenceFragmentCompat implemen } private void createPref() { + + getPreferenceScreen().removeAll(); + addPreferencesFromResource(R.xml.pref_timelines); + PreferenceScreen preferenceScreen = getPreferenceScreen(); ListPreference SET_LOAD_MEDIA_TYPE = findPreference(getString(R.string.SET_LOAD_MEDIA_TYPE)); if (SET_LOAD_MEDIA_TYPE != null) { SET_LOAD_MEDIA_TYPE.getContext().setTheme(Helper.dialogStyle()); } + ListPreference SET_TRANSLATOR = findPreference(getString(R.string.SET_TRANSLATOR)); + if (SET_TRANSLATOR != null) { + SET_TRANSLATOR.getContext().setTheme(Helper.dialogStyle()); + } + ListPreference SET_TRANSLATOR_VERSION = findPreference(getString(R.string.SET_TRANSLATOR_VERSION)); + if (SET_TRANSLATOR_VERSION != null) { + SET_TRANSLATOR_VERSION.getContext().setTheme(Helper.dialogStyle()); + } + EditTextPreference SET_TRANSLATOR_API_KEY = findPreference(getString(R.string.SET_TRANSLATOR_API_KEY)); + if (SET_TRANSLATOR != null && SET_TRANSLATOR.getValue().equals("FEDILAB")) { + if (SET_TRANSLATOR_API_KEY != null) { + preferenceScreen.removePreferenceRecursively("SET_TRANSLATOR_API_KEY"); + } + if (SET_TRANSLATOR_VERSION != null) { + preferenceScreen.removePreferenceRecursively("SET_TRANSLATOR_VERSION"); + } + } } @Override @@ -44,8 +67,10 @@ public class FragmentTimelinesSettings extends PreferenceFragmentCompat implemen if (getActivity() != null) { SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(requireActivity()); SharedPreferences.Editor editor = sharedpreferences.edit(); - editor.apply(); + if (key.compareToIgnoreCase(getString(R.string.SET_TRANSLATOR)) == 0) { + createPref(); + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8644912b..b04300af 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -766,6 +766,26 @@ Wifi only Ask + + + Fedilab + DeepL + + + Free + Pro + + + + FEDILAB + DEEPL + + + + FREE + PRO + + 15 minutes 30 minutes @@ -1400,6 +1420,12 @@ SET_NOTIF_VALIDATION SET_DISPLAY_BOOKMARK SET_DISPLAY_TRANSLATE + SET_TRANSLATOR + SET_TRANSLATOR_VERSION + + SET_TRANSLATOR_API_KEY + + SET_NOTIF_VALIDATION_FAV SET_DISPLAY_COUNTER_FAV_BOOST SET_REMOVE_LEFT_MARGIN @@ -2116,4 +2142,9 @@ Manage accounts Remove left margin Remove the left margin in timelines to make messages more compact + Translator + Translator + Translator API key + Version + Translator version \ No newline at end of file diff --git a/app/src/main/res/xml/pref_timelines.xml b/app/src/main/res/xml/pref_timelines.xml index 4ba37efa..34ea407f 100644 --- a/app/src/main/res/xml/pref_timelines.xml +++ b/app/src/main/res/xml/pref_timelines.xml @@ -54,6 +54,32 @@ app:singleLineTitle="false" app:title="@string/set_display_translate_indication" /> + + + + +