From 74e671fa37adc6c35097e0d60a9e7c32053d2afc Mon Sep 17 00:00:00 2001 From: M66B Date: Sun, 18 Sep 2022 14:06:09 +0200 Subject: [PATCH] Added block toolbar --- FAQ.md | 7 ++ .../eu/faircode/email/FragmentCompose.java | 66 +++++++++++++++++++ app/src/main/res/layout/fragment_compose.xml | 15 ++++- .../res/menu/action_compose_paragraph.xml | 22 +++++++ app/src/main/res/menu/menu_compose.xml | 8 +++ .../main/res/menu/popup_style_alignment.xml | 17 +++++ .../main/res/menu/popup_style_indentation.xml | 11 ++++ app/src/main/res/menu/popup_style_list.xml | 19 ++++++ app/src/main/res/values/strings.xml | 1 + 9 files changed, 165 insertions(+), 1 deletion(-) create mode 100644 app/src/main/res/menu/action_compose_paragraph.xml create mode 100644 app/src/main/res/menu/popup_style_alignment.xml create mode 100644 app/src/main/res/menu/popup_style_indentation.xml create mode 100644 app/src/main/res/menu/popup_style_list.xml diff --git a/FAQ.md b/FAQ.md index 40ed1adb3c..9daa7b29a7 100644 --- a/FAQ.md +++ b/FAQ.md @@ -3735,6 +3735,13 @@ See [this FAQ](#user-content-faq71) for a header condition to recognize receipts
+*Block toolbar (version 1.1967+)* + +When enabled in the three-dots overflow menu of the message editor, +a toolbar to perform operations (align text, insert list, indent text, insert blockquote) on a block of text (consecutive non-empty lines) will be shown. + +
+ **(126) Can message previews be sent to my wearable?** diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 6847bab3b2..c7d92fe068 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -272,6 +272,7 @@ public class FragmentCompose extends FragmentBase { private ImageButton ibReferenceImages; private View vwAnchor; private TextViewAutoCompleteAction etSearch; + private BottomNavigationView block_bar; private BottomNavigationView style_bar; private BottomNavigationView media_bar; private BottomNavigationView bottom_navigation; @@ -291,6 +292,7 @@ public class FragmentCompose extends FragmentBase { private String display_font; private boolean dsn = true; private Integer encrypt = null; + private boolean block = false; private boolean media = true; private boolean compact = false; private int zoom = 0; @@ -347,8 +349,11 @@ public class FragmentCompose extends FragmentBase { super.onCreate(savedInstanceState); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + boolean experiments = prefs.getBoolean("experiments", false); + compose_font = prefs.getString("compose_font", ""); display_font = prefs.getString("display_font", ""); + block = experiments && prefs.getBoolean("compose_block", false); media = prefs.getBoolean("compose_media", true); compact = prefs.getBoolean("compose_compact", false); zoom = prefs.getInt("compose_zoom", compact ? 0 : 1); @@ -394,6 +399,7 @@ public class FragmentCompose extends FragmentBase { ibReferenceImages = view.findViewById(R.id.ibReferenceImages); vwAnchor = view.findViewById(R.id.vwAnchor); etSearch = view.findViewById(R.id.etSearch); + block_bar = view.findViewById(R.id.block_bar); style_bar = view.findViewById(R.id.style_bar); media_bar = view.findViewById(R.id.media_bar); bottom_navigation = view.findViewById(R.id.bottom_navigation); @@ -1011,6 +1017,51 @@ public class FragmentCompose extends FragmentBase { } }); + block_bar.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + int action = item.getItemId(); + if (action == R.id.menu_blockquote) { + Pair block = StyleHelper.getParagraph(etBody, true); + if (block == null) + return false; + StyleHelper.setBlockQuote(etBody, block.first, block.second, false); + return true; + } else { + PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(getContext(), getViewLifecycleOwner(), block_bar.findViewById(action)); + if (action == R.id.menu_alignment) + popupMenu.inflate(R.menu.popup_style_alignment); + else if (action == R.id.menu_list) + popupMenu.inflate(R.menu.popup_style_list); + else if (action == R.id.menu_indentation) + popupMenu.inflate(R.menu.popup_style_indentation); + popupMenu.insertIcons(getContext()); + popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + int itemId = item.getItemId(); + boolean level = (itemId == R.id.menu_style_list_decrease || itemId == R.id.menu_style_list_increase); + Pair block = StyleHelper.getParagraph(etBody, !level); + if (block == null) + return false; + if (action == R.id.menu_alignment) + StyleHelper.setAlignment(item.getItemId(), etBody, block.first, block.second, false); + else if (action == R.id.menu_list) { + if (level) + StyleHelper.setListLevel(itemId, etBody, block.first, block.second, false); + else + StyleHelper.setList(itemId, etBody, block.first, block.second, false); + } else if (action == R.id.menu_indentation) + StyleHelper.setIndentation(item.getItemId(), etBody, block.first, block.second, false); + return true; + } + }); + popupMenu.show(); + return true; + } + } + }); + style_bar.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { @Override public boolean onNavigationItemSelected(@NonNull MenuItem item) { @@ -1102,6 +1153,7 @@ public class FragmentCompose extends FragmentBase { ibReferenceImages.setVisibility(View.GONE); tvReference.setVisibility(View.GONE); etSearch.setVisibility(View.GONE); + block_bar.setVisibility(View.GONE); style_bar.setVisibility(View.GONE); media_bar.setVisibility(View.GONE); bottom_navigation.setVisibility(View.GONE); @@ -1848,6 +1900,7 @@ public class FragmentCompose extends FragmentBase { ibZoom.setEnabled(state == State.LOADED); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean experiments = prefs.getBoolean("experiments", false); boolean save_drafts = prefs.getBoolean("save_drafts", true); boolean send_chips = prefs.getBoolean("send_chips", true); boolean send_dialog = prefs.getBoolean("send_dialog", true); @@ -1857,6 +1910,7 @@ public class FragmentCompose extends FragmentBase { menu.findItem(R.id.menu_send_chips).setChecked(send_chips); menu.findItem(R.id.menu_send_dialog).setChecked(send_dialog); menu.findItem(R.id.menu_image_dialog).setChecked(image_dialog); + menu.findItem(R.id.menu_block).setChecked(block).setVisible(experiments); menu.findItem(R.id.menu_media).setChecked(media); menu.findItem(R.id.menu_compact).setChecked(compact); @@ -1929,6 +1983,9 @@ public class FragmentCompose extends FragmentBase { } else if (itemId == R.id.menu_image_dialog) { onMenuImageDialog(); return true; + } else if (itemId == R.id.menu_block) { + onMenuBlockBar(); + return true; } else if (itemId == R.id.menu_media) { onMenuMediaBar(); return true; @@ -2082,6 +2139,14 @@ public class FragmentCompose extends FragmentBase { prefs.edit().putBoolean("image_dialog", !image_dialog).apply(); } + private void onMenuBlockBar() { + block = !block; + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + prefs.edit().putBoolean("compose_block", block).apply(); + block_bar.setVisibility(block ? View.VISIBLE : View.GONE); + invalidateOptionsMenu(); + } + private void onMenuMediaBar() { media = !media; SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); @@ -6767,6 +6832,7 @@ public class FragmentCompose extends FragmentBase { @Override protected void onPostExecute(Bundle args) { pbWait.setVisibility(View.GONE); + block_bar.setVisibility(block ? View.VISIBLE : View.GONE); media_bar.setVisibility(media ? View.VISIBLE : View.GONE); bottom_navigation.getMenu().findItem(R.id.action_undo).setVisible(draft.revision > 1); bottom_navigation.getMenu().findItem(R.id.action_redo).setVisible(draft.revision < draft.revisions); diff --git a/app/src/main/res/layout/fragment_compose.xml b/app/src/main/res/layout/fragment_compose.xml index 0c41c474c2..cc6b0f9e4e 100644 --- a/app/src/main/res/layout/fragment_compose.xml +++ b/app/src/main/res/layout/fragment_compose.xml @@ -577,10 +577,23 @@ android:maxLines="1" android:padding="6dp" app:end_drawable="@drawable/twotone_fast_forward_24" - app:layout_constraintBottom_toTopOf="@id/style_bar" + app:layout_constraintBottom_toTopOf="@id/block_bar" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" /> + + + + + + + + + + + diff --git a/app/src/main/res/menu/menu_compose.xml b/app/src/main/res/menu/menu_compose.xml index cb66081824..63be07013f 100644 --- a/app/src/main/res/menu/menu_compose.xml +++ b/app/src/main/res/menu/menu_compose.xml @@ -51,6 +51,14 @@ android:title="@string/title_image_dialog" app:showAsAction="never" /> + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/popup_style_indentation.xml b/app/src/main/res/menu/popup_style_indentation.xml new file mode 100644 index 0000000000..e713f224bd --- /dev/null +++ b/app/src/main/res/menu/popup_style_indentation.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/menu/popup_style_list.xml b/app/src/main/res/menu/popup_style_list.xml new file mode 100644 index 0000000000..ee583f603f --- /dev/null +++ b/app/src/main/res/menu/popup_style_list.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 02b511e099..cf2487fa11 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1469,6 +1469,7 @@ Save drafts on the server Show send options Show image options + Block toolbar Media toolbar Manage local contacts Insert contact group