From 6a4fb2df94ce103d628352c8811b27cee7f0b02f Mon Sep 17 00:00:00 2001 From: M66B Date: Thu, 30 Jan 2020 20:52:18 +0100 Subject: [PATCH] Added volume navigation option --- .../java/eu/faircode/email/ActivityBase.java | 23 ++++++++--- .../eu/faircode/email/FragmentAccount.java | 7 +++- .../java/eu/faircode/email/FragmentBase.java | 4 +- .../eu/faircode/email/FragmentCompose.java | 9 ++++- .../eu/faircode/email/FragmentFolder.java | 7 +++- .../eu/faircode/email/FragmentIdentity.java | 7 +++- .../eu/faircode/email/FragmentMessages.java | 39 ++++++++++++++++++- .../email/FragmentOptionsBehavior.java | 12 +++++- .../res/layout/fragment_options_behavior.xml | 13 ++++++- app/src/main/res/values/strings.xml | 1 + 10 files changed, 105 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/eu/faircode/email/ActivityBase.java b/app/src/main/java/eu/faircode/email/ActivityBase.java index 49c774f875..cca34791ec 100644 --- a/app/src/main/java/eu/faircode/email/ActivityBase.java +++ b/app/src/main/java/eu/faircode/email/ActivityBase.java @@ -28,6 +28,7 @@ import android.content.res.Configuration; import android.os.Build; import android.os.Bundle; import android.os.PowerManager; +import android.view.KeyEvent; import android.view.MenuItem; import android.view.View; import android.view.Window; @@ -52,7 +53,7 @@ import java.util.Map; abstract class ActivityBase extends AppCompatActivity implements SharedPreferences.OnSharedPreferenceChangeListener { private Context originalContext; private boolean contacts; - private List backPressedListeners = new ArrayList<>(); + private List keyPressedListeners = new ArrayList<>(); @Override protected void attachBaseContext(Context base) { @@ -348,15 +349,15 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc return Helper.hasPermission(this, name); } - void addBackPressedListener(final IBackPressedListener listener, LifecycleOwner owner) { + void addKeyPressedListener(final IKeyPressedListener listener, LifecycleOwner owner) { Log.d("Adding back listener=" + listener); - backPressedListeners.add(listener); + keyPressedListeners.add(listener); owner.getLifecycle().addObserver(new LifecycleObserver() { @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) public void onDestroyed() { Log.d("Removing back listener=" + listener); - backPressedListeners.remove(listener); + keyPressedListeners.remove(listener); } }); } @@ -368,6 +369,14 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc super.onBackPressed(); } + public boolean dispatchKeyEvent(KeyEvent event) { + int keyCode = event.getKeyCode(); + for (IKeyPressedListener listener : keyPressedListeners) + if (listener.onKeyPressed(keyCode)) + return true; + return super.dispatchKeyEvent(event); + } + @Override public boolean onOptionsItemSelected(@NonNull MenuItem item) { switch (item.getItemId()) { @@ -381,13 +390,15 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc } protected boolean backHandled() { - for (IBackPressedListener listener : backPressedListeners) + for (IKeyPressedListener listener : keyPressedListeners) if (listener.onBackPressed()) return true; return false; } - public interface IBackPressedListener { + public interface IKeyPressedListener { + boolean onKeyPressed(int keyCode); + boolean onBackPressed(); } } diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java index 9bf70ee5e3..dfc2f1c617 100644 --- a/app/src/main/java/eu/faircode/email/FragmentAccount.java +++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java @@ -414,7 +414,12 @@ public class FragmentAccount extends FragmentBase { } }); - addBackPressedListener(new ActivityBase.IBackPressedListener() { + addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + @Override + public boolean onKeyPressed(int keyCode) { + return false; + } + @Override public boolean onBackPressed() { onSave(true); diff --git a/app/src/main/java/eu/faircode/email/FragmentBase.java b/app/src/main/java/eu/faircode/email/FragmentBase.java index 9cf81b04fa..e68151b95a 100644 --- a/app/src/main/java/eu/faircode/email/FragmentBase.java +++ b/app/src/main/java/eu/faircode/email/FragmentBase.java @@ -272,8 +272,8 @@ public class FragmentBase extends Fragment { return activity.hasPermission(name); } - void addBackPressedListener(ActivityBase.IBackPressedListener listener) { - ((ActivityBase) getActivity()).addBackPressedListener(listener, getViewLifecycleOwner()); + void addKeyPressedListener(ActivityBase.IKeyPressedListener listener) { + ((ActivityBase) getActivity()).addKeyPressedListener(listener, getViewLifecycleOwner()); } void addBillingListener(ActivityBilling.IBillingListener listener) { diff --git a/app/src/main/java/eu/faircode/email/FragmentCompose.java b/app/src/main/java/eu/faircode/email/FragmentCompose.java index 25328529e5..b22cb5ce62 100644 --- a/app/src/main/java/eu/faircode/email/FragmentCompose.java +++ b/app/src/main/java/eu/faircode/email/FragmentCompose.java @@ -630,7 +630,7 @@ public class FragmentCompose extends FragmentBase { //view.getViewTreeObserver().addOnGlobalLayoutListener(layoutListener); - addBackPressedListener(onBackPressedListener); + addKeyPressedListener(onBackPressedListener); // Initialize setHasOptionsMenu(true); @@ -4165,7 +4165,12 @@ public class FragmentCompose extends FragmentBase { } }; - private ActivityBase.IBackPressedListener onBackPressedListener = new ActivityBase.IBackPressedListener() { + private ActivityBase.IKeyPressedListener onBackPressedListener = new ActivityBase.IKeyPressedListener() { + @Override + public boolean onKeyPressed(int keyCode) { + return false; + } + @Override public boolean onBackPressed() { if (getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) diff --git a/app/src/main/java/eu/faircode/email/FragmentFolder.java b/app/src/main/java/eu/faircode/email/FragmentFolder.java index ba12a1e8c8..2f72232dd3 100644 --- a/app/src/main/java/eu/faircode/email/FragmentFolder.java +++ b/app/src/main/java/eu/faircode/email/FragmentFolder.java @@ -171,7 +171,12 @@ public class FragmentFolder extends FragmentBase { } }); - addBackPressedListener(new ActivityBase.IBackPressedListener() { + addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + @Override + public boolean onKeyPressed(int keyCode) { + return false; + } + @Override public boolean onBackPressed() { onSave(true); diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java index 1c573175e4..814bab3d91 100644 --- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java +++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java @@ -444,7 +444,12 @@ public class FragmentIdentity extends FragmentBase { } }); - addBackPressedListener(new ActivityBase.IBackPressedListener() { + addKeyPressedListener(new ActivityBase.IKeyPressedListener() { + @Override + public boolean onKeyPressed(int keyCode) { + return false; + } + @Override public boolean onBackPressed() { onSave(true); diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index 61f5df3307..9b4f5c4347 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -62,6 +62,7 @@ import android.util.Base64; import android.util.LongSparseArray; import android.util.Pair; import android.util.TypedValue; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -1081,7 +1082,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } }); - addBackPressedListener(onBackPressedListener); + addKeyPressedListener(onBackPressedListener); // Initialize if (cards && !Helper.isDarkTheme(getContext())) @@ -4051,7 +4052,41 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. return (filter_seen || filter_unflagged); } - private ActivityBase.IBackPressedListener onBackPressedListener = new ActivityBase.IBackPressedListener() { + private ActivityBase.IKeyPressedListener onBackPressedListener = new ActivityBase.IKeyPressedListener() { + @Override + public boolean onKeyPressed(int keyCode) { + if (viewType != AdapterMessage.ViewType.THREAD) + return false; + + Context context = getContext(); + if (context == null) + return false; + + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean volumenav = prefs.getBoolean("volumenav", false); + if (!volumenav) + return false; + + switch (keyCode) { + case KeyEvent.KEYCODE_VOLUME_UP: + if (next == null) { + Animation bounce = AnimationUtils.loadAnimation(getContext(), R.anim.bounce_left); + view.startAnimation(bounce); + } else + navigate(next, false); + return true; + case KeyEvent.KEYCODE_VOLUME_DOWN: + if (prev == null) { + Animation bounce = AnimationUtils.loadAnimation(getContext(), R.anim.bounce_right); + view.startAnimation(bounce); + } else + navigate(prev, true); + return true; + default: + return false; + } + } + @Override public boolean onBackPressed() { if (selectionTracker != null && selectionTracker.hasSelection()) { diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java b/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java index 87688d6cfc..5672e11ce8 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsBehavior.java @@ -46,6 +46,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe private SwitchCompat swAutoScroll; private SwitchCompat swDoubleTap; private SwitchCompat swSwipeNav; + private SwitchCompat swVolumeNav; private SwitchCompat swReversed; private SwitchCompat swAutoExpand; private SwitchCompat swExpandAll; @@ -62,7 +63,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe private NumberPicker npDefaultSnooze; private final static String[] RESET_OPTIONS = new String[]{ - "double_back", "pull", "autoscroll", "doubletap", "swipenav", "reversed", + "double_back", "pull", "autoscroll", "doubletap", "swipenav", "volumenav", "reversed", "autoexpand", "expand_all", "expand_one", "collapse_multiple", "autoclose", "onclose", "quick_filter", "quick_scroll", "autoread", "autounflag", "automove", "discard_delete", "default_snooze" @@ -83,6 +84,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe swAutoScroll = view.findViewById(R.id.swAutoScroll); swDoubleTap = view.findViewById(R.id.swDoubleTap); swSwipeNav = view.findViewById(R.id.swSwipeNav); + swVolumeNav = view.findViewById(R.id.swVolumeNav); swReversed = view.findViewById(R.id.swReversed); swAutoExpand = view.findViewById(R.id.swAutoExpand); swExpandAll = view.findViewById(R.id.swExpandAll); @@ -142,6 +144,13 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe } }); + swVolumeNav.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("volumenav", checked).apply(); + } + }); + swReversed.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { @@ -305,6 +314,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe swAutoScroll.setChecked(prefs.getBoolean("autoscroll", true)); swDoubleTap.setChecked(prefs.getBoolean("doubletap", false)); swSwipeNav.setChecked(prefs.getBoolean("swipenav", true)); + swVolumeNav.setChecked(prefs.getBoolean("volumenav", false)); swReversed.setChecked(prefs.getBoolean("reversed", false)); swAutoExpand.setChecked(prefs.getBoolean("autoexpand", true)); diff --git a/app/src/main/res/layout/fragment_options_behavior.xml b/app/src/main/res/layout/fragment_options_behavior.xml index dbca6deba0..679d8edc53 100644 --- a/app/src/main/res/layout/fragment_options_behavior.xml +++ b/app/src/main/res/layout/fragment_options_behavior.xml @@ -70,6 +70,17 @@ app:layout_constraintTop_toBottomOf="@id/swDoubleTap" app:switchPadding="12dp" /> + + Scroll to top on receiving new messages Double tap to mark message read/unread Swipe left/right to go to next/previous conversation + Volume up/down to go to next/previous conversation Reverse navigation direction Automatically expand messages Automatically expand all read messages