From 21923526bc3b60998dfe15f1e1277c38bdb62aca Mon Sep 17 00:00:00 2001 From: M66B Date: Wed, 28 Jul 2021 10:43:17 +0200 Subject: [PATCH] Use FAB for compose/translate --- .../eu/faircode/email/FragmentCompose.java | 233 +++++++++--------- app/src/main/res/layout/fragment_compose.xml | 29 ++- 2 files changed, 135 insertions(+), 127 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index a7d35821c9..0a54975a41 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -121,6 +121,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.bottomnavigation.BottomNavigationView; import com.google.android.material.bottomnavigation.LabelVisibilityMode; +import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.google.android.material.snackbar.Snackbar; import org.bouncycastle.cert.jcajce.JcaCertStore; @@ -241,7 +242,6 @@ public class FragmentCompose extends FragmentBase { private TextView tvDsn; private TextView tvPlainTextOnly; private EditTextCompose etBody; - private ImageButton ibTranslate; private TextView tvNoInternet; private TextView tvSignature; private CheckBox cbSignature; @@ -250,6 +250,7 @@ public class FragmentCompose extends FragmentBase { private ImageButton ibCloseRefHint; private ImageButton ibReferenceEdit; private ImageButton ibReferenceImages; + private FloatingActionButton fabTranslate; private BottomNavigationView style_bar; private BottomNavigationView media_bar; private BottomNavigationView bottom_navigation; @@ -358,7 +359,6 @@ public class FragmentCompose extends FragmentBase { tvDsn = view.findViewById(R.id.tvDsn); tvPlainTextOnly = view.findViewById(R.id.tvPlainTextOnly); etBody = view.findViewById(R.id.etBody); - ibTranslate = view.findViewById(R.id.ibTranslate); tvNoInternet = view.findViewById(R.id.tvNoInternet); tvSignature = view.findViewById(R.id.tvSignature); cbSignature = view.findViewById(R.id.cbSignature); @@ -367,6 +367,7 @@ public class FragmentCompose extends FragmentBase { ibCloseRefHint = view.findViewById(R.id.ibCloseRefHint); ibReferenceEdit = view.findViewById(R.id.ibReferenceEdit); ibReferenceImages = view.findViewById(R.id.ibReferenceImages); + fabTranslate = view.findViewById(R.id.fabTranslate); style_bar = view.findViewById(R.id.style_bar); media_bar = view.findViewById(R.id.media_bar); bottom_navigation = view.findViewById(R.id.bottom_navigation); @@ -716,116 +717,6 @@ public class FragmentCompose extends FragmentBase { } }); - ibTranslate.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - List languages = DeepL.getTargetLanguages(getContext()); - if (languages == null) - return; - - boolean canTranslate = - (DeepL.canTranslate(getContext()) && - DeepL.getParagraph(etBody) != null); - - PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), v); - - popupMenu.getMenu().add(Menu.NONE, 1, 1, R.string.title_translate_configure); - - for (int i = 0; i < languages.size(); i++) { - DeepL.Language lang = languages.get(i); - MenuItem item = popupMenu.getMenu().add(Menu.NONE, i + 2, i + 2, lang.name) - .setIntent(new Intent().putExtra("target", lang.target)); - if (lang.icon != null) - item.setIcon(lang.icon); - item.setEnabled(canTranslate); - } - - popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - if (item.getItemId() == 1) { - DeepL.FragmentDialogDeepL fragment = new DeepL.FragmentDialogDeepL(); - fragment.show(getParentFragmentManager(), "deepl:configure"); - } else { - String target = item.getIntent().getStringExtra("target"); - onMenuTranslate(target); - } - return true; - } - }); - - popupMenu.showWithIcons(getContext(), v); - } - - private void onMenuTranslate(String target) { - final Pair paragraph = DeepL.getParagraph(etBody); - if (paragraph == null) - return; - - Editable edit = etBody.getText(); - String text = edit.subSequence(paragraph.first, paragraph.second).toString(); - - Bundle args = new Bundle(); - args.putString("target", target); - args.putString("text", text); - - new SimpleTask() { - @Override - protected void onPreExecute(Bundle args) { - ToastEx.makeText(getContext(), R.string.title_translating, Toast.LENGTH_SHORT).show(); - } - - @Override - protected DeepL.Translation onExecute(Context context, Bundle args) throws Throwable { - String target = args.getString("target"); - String text = args.getString("text"); - return DeepL.translate(text, target, context); - } - - @Override - protected void onExecuted(Bundle args, DeepL.Translation translation) { - if (paragraph.second > edit.length()) - return; - - FragmentActivity activity = getActivity(); - if (activity == null) - return; - - Context context = getContext(); - SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); - - // Insert translated text - edit.insert(paragraph.second, "\n\n" + translation.translated_text); - etBody.setSelection(paragraph.second + 2 + translation.translated_text.length()); - - boolean small = prefs.getBoolean("deepl_small", false); - if (small) { - RelativeSizeSpan[] spans = edit.getSpans( - paragraph.first, paragraph.second, RelativeSizeSpan.class); - for (RelativeSizeSpan span : spans) - edit.removeSpan(span); - edit.setSpan(new RelativeSizeSpan(HtmlHelper.FONT_SMALL), - paragraph.first, paragraph.second, - Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - - // Updated frequency - String key = "translated_" + args.getString("target"); - int count = prefs.getInt(key, 0); - prefs.edit().putInt(key, count + 1).apply(); - - activity.invalidateOptionsMenu(); - } - - @Override - protected void onException(Bundle args, Throwable ex) { - Throwable exex = new Throwable("DeepL", ex); - Log.unexpectedError(getParentFragmentManager(), exex, false); - } - }.execute(FragmentCompose.this, args, "compose:translate"); - } - }); - tvSignature.setTypeface(monospaced ? Typeface.MONOSPACE : Typeface.DEFAULT); cbSignature.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @@ -924,6 +815,13 @@ public class FragmentCompose extends FragmentBase { } }); + fabTranslate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + onTranslate(v); + } + }); + style_bar.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { @@ -1006,13 +904,13 @@ public class FragmentCompose extends FragmentBase { grpAttachments.setVisibility(View.GONE); tvNoInternet.setVisibility(View.GONE); grpBody.setVisibility(View.GONE); - ibTranslate.setVisibility( - DeepL.isAvailable(getContext()) ? View.VISIBLE : View.GONE); grpSignature.setVisibility(View.GONE); grpReferenceHint.setVisibility(View.GONE); ibReferenceEdit.setVisibility(View.GONE); ibReferenceImages.setVisibility(View.GONE); tvReference.setVisibility(View.GONE); + fabTranslate.setVisibility( + DeepL.isAvailable(getContext()) ? View.VISIBLE : View.GONE); style_bar.setVisibility(View.GONE); media_bar.setVisibility(View.GONE); bottom_navigation.setVisibility(View.GONE); @@ -2065,6 +1963,113 @@ public class FragmentCompose extends FragmentBase { fragmentTransaction.commit(); } + private void onTranslate(View anchor) { + final Context context = anchor.getContext(); + + List languages = DeepL.getTargetLanguages(context); + if (languages == null) + languages = new ArrayList<>(); + + Pair paragraph = DeepL.getParagraph(etBody); + boolean canTranslate = (DeepL.canTranslate(context) && paragraph != null); + + PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, getViewLifecycleOwner(), anchor); + + popupMenu.getMenu().add(Menu.NONE, 1, 1, R.string.title_translate_configure); + + for (int i = 0; i < languages.size(); i++) { + DeepL.Language lang = languages.get(i); + MenuItem item = popupMenu.getMenu().add(Menu.NONE, i + 2, i + 2, lang.name) + .setIntent(new Intent().putExtra("target", lang.target)); + if (lang.icon != null) + item.setIcon(lang.icon); + item.setEnabled(canTranslate); + } + + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + if (item.getItemId() == 1) { + DeepL.FragmentDialogDeepL fragment = new DeepL.FragmentDialogDeepL(); + fragment.show(getParentFragmentManager(), "deepl:configure"); + } else { + String target = item.getIntent().getStringExtra("target"); + onMenuTranslate(target); + } + return true; + } + + private void onMenuTranslate(String target) { + final Pair paragraph = DeepL.getParagraph(etBody); + if (paragraph == null) + return; + + Editable edit = etBody.getText(); + String text = edit.subSequence(paragraph.first, paragraph.second).toString(); + + Bundle args = new Bundle(); + args.putString("target", target); + args.putString("text", text); + + new SimpleTask() { + @Override + protected void onPreExecute(Bundle args) { + ToastEx.makeText(context, R.string.title_translating, Toast.LENGTH_SHORT).show(); + } + + @Override + protected DeepL.Translation onExecute(Context context, Bundle args) throws Throwable { + String target = args.getString("target"); + String text = args.getString("text"); + return DeepL.translate(text, target, context); + } + + @Override + protected void onExecuted(Bundle args, DeepL.Translation translation) { + if (paragraph.second > edit.length()) + return; + + FragmentActivity activity = getActivity(); + if (activity == null) + return; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + + // Insert translated text + edit.insert(paragraph.second, "\n\n" + translation.translated_text); + etBody.setSelection(paragraph.second + 2 + translation.translated_text.length()); + + boolean small = prefs.getBoolean("deepl_small", false); + if (small) { + RelativeSizeSpan[] spans = edit.getSpans( + paragraph.first, paragraph.second, RelativeSizeSpan.class); + for (RelativeSizeSpan span : spans) + edit.removeSpan(span); + edit.setSpan(new RelativeSizeSpan(HtmlHelper.FONT_SMALL), + paragraph.first, paragraph.second, + Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + } + + // Updated frequency + String key = "translated_" + args.getString("target"); + int count = prefs.getInt(key, 0); + prefs.edit().putInt(key, count + 1).apply(); + + activity.invalidateOptionsMenu(); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + Throwable exex = new Throwable("DeepL", ex); + Log.unexpectedError(getParentFragmentManager(), exex, false); + } + }.execute(FragmentCompose.this, args, "compose:translate"); + } + }); + + popupMenu.showWithIcons(context, anchor); + } + private boolean onActionStyle(int action, View anchor) { Log.i("Style action=" + action); return StyleHelper.apply(action, getViewLifecycleOwner(), anchor, etBody); diff --git a/app/src/main/res/layout/fragment_compose.xml b/app/src/main/res/layout/fragment_compose.xml index 2f61b6a8b0..26aa8dcf75 100644 --- a/app/src/main/res/layout/fragment_compose.xml +++ b/app/src/main/res/layout/fragment_compose.xml @@ -307,18 +307,6 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvPlainTextOnly" /> - - + app:layout_constraintTop_toBottomOf="@+id/etBody" /> + +