From ede7305fe94760fb222763cb728cd83df6bc6450 Mon Sep 17 00:00:00 2001 From: Schuyler Cebulskie Date: Fri, 16 Jun 2023 20:34:13 -0400 Subject: [PATCH] feat: Add haptic feedback on boost/favourite/bookmark --- .../joinmastodon/android/GlobalUserPreferences.java | 2 ++ .../android/fragments/settings/BehaviourFragment.java | 5 +++++ .../fragments/settings/SettingsBaseFragment.java | 9 +++++++++ .../ui/displayitems/FooterStatusDisplayItem.java | 11 +++++++++++ .../drawable/ic_fluent_phone_vibrate_24_filled.xml | 9 +++++++++ mastodon/src/main/res/values/strings_mo.xml | 2 ++ 6 files changed, 38 insertions(+) create mode 100644 mastodon/src/main/res/drawable/ic_fluent_phone_vibrate_24_filled.xml diff --git a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java index 53be8a16d..bc4f92dc5 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java @@ -52,6 +52,7 @@ public class GlobalUserPreferences{ public static boolean doubleTapToSwipe; public static boolean compactReblogReplyLine; public static boolean confirmBeforeReblog; + public static boolean hapticFeedback; public static boolean replyLineAboveHeader; public static boolean swapBookmarkWithBoostAction; public static boolean loadRemoteAccountFollowers; @@ -139,6 +140,7 @@ public class GlobalUserPreferences{ replyLineAboveHeader=prefs.getBoolean("replyLineAboveHeader", true); compactReblogReplyLine=prefs.getBoolean("compactReblogReplyLine", true); confirmBeforeReblog=prefs.getBoolean("confirmBeforeReblog", false); + hapticFeedback=prefs.getBoolean("hapticFeedback", true); swapBookmarkWithBoostAction=prefs.getBoolean("swapBookmarkWithBoostAction", false); loadRemoteAccountFollowers=prefs.getBoolean("loadRemoteAccountFollowers", true); mentionRebloggerAutomatically=prefs.getBoolean("mentionRebloggerAutomatically", false); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java index ef6b82235..cdd1409c7 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/BehaviourFragment.java @@ -1,5 +1,6 @@ package org.joinmastodon.android.fragments.settings; +import android.os.Build; import android.view.Gravity; import android.view.MenuItem; import android.view.ViewGroup; @@ -63,6 +64,10 @@ public class BehaviourFragment extends SettingsBaseFragment{ GlobalUserPreferences.save(); needAppRestart=true; })); + items.add(new SwitchItem(R.string.mo_haptic_feedback, R.string.mo_setting_haptic_feedback, R.drawable.ic_fluent_phone_vibrate_24_filled, GlobalUserPreferences.hapticFeedback, i -> { + GlobalUserPreferences.hapticFeedback = i.checked; + GlobalUserPreferences.save(); + }, Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)); items.add(new SwitchItem(R.string.sk_settings_confirm_before_reblog, R.drawable.ic_fluent_checkmark_circle_24_regular, GlobalUserPreferences.confirmBeforeReblog, i->{ GlobalUserPreferences.confirmBeforeReblog=i.checked; GlobalUserPreferences.save(); diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java index ae30f0689..3bd3f85a9 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsBaseFragment.java @@ -264,6 +264,15 @@ public abstract class SettingsBaseFragment extends MastodonToolbarFragment imple this.onChanged=onChanged; } + public SwitchItem(@StringRes int title, @StringRes int summary, @DrawableRes int icon, boolean checked, Consumer onChanged, boolean enabled){ + this.title=getString(title); + this.summary=getString(summary); + this.icon=icon; + this.checked=checked; + this.onChanged=onChanged; + this.enabled=enabled; + } + public SwitchItem(@StringRes int title, @DrawableRes int icon, boolean checked, Consumer onChanged, boolean enabled){ this.title=getString(title); this.icon=icon; diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java index 9f45de6fe..2f44927b1 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/FooterStatusDisplayItem.java @@ -5,7 +5,9 @@ import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Drawable; +import android.os.Build; import android.os.Bundle; +import android.view.HapticFeedbackConstants; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -244,6 +246,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ if(status == null) return; boost.setSelected(!status.reblogged); + vibrateForAction(boost, !status.reblogged); AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setReblogged(status, !status.reblogged, null, r->boostConsumer(v, r)); } ); @@ -361,6 +364,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ if(status == null) return; favorite.setSelected(!status.favourited); + vibrateForAction(favorite, !status.favourited); AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setFavorited(status, !status.favourited, r->{ if (status.favourited) { v.startAnimation(GlobalUserPreferences.reduceMotion ? opacityIn : animSet); @@ -406,6 +410,7 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ if(status == null) return; bookmark.setSelected(!status.bookmarked); + vibrateForAction(bookmark, !status.bookmarked); AccountSessionManager.getInstance().getAccount(item.accountID).getStatusInteractionController().setBookmarked(status, !status.bookmarked, r->{ v.startAnimation(opacityIn); }); @@ -459,5 +464,11 @@ public class FooterStatusDisplayItem extends StatusDisplayItem{ return R.string.button_share; return 0; } + + private static void vibrateForAction(View view, boolean isPositive) { + if (!GlobalUserPreferences.hapticFeedback) return; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) return; + view.performHapticFeedback(isPositive ? HapticFeedbackConstants.CONFIRM : HapticFeedbackConstants.REJECT); + } } } diff --git a/mastodon/src/main/res/drawable/ic_fluent_phone_vibrate_24_filled.xml b/mastodon/src/main/res/drawable/ic_fluent_phone_vibrate_24_filled.xml new file mode 100644 index 000000000..c182f3802 --- /dev/null +++ b/mastodon/src/main/res/drawable/ic_fluent_phone_vibrate_24_filled.xml @@ -0,0 +1,9 @@ + + + diff --git a/mastodon/src/main/res/values/strings_mo.xml b/mastodon/src/main/res/values/strings_mo.xml index 89790e4d0..4b397d17c 100644 --- a/mastodon/src/main/res/values/strings_mo.xml +++ b/mastodon/src/main/res/values/strings_mo.xml @@ -53,6 +53,7 @@ Open in App Double tap to swipe between tabs + Haptic feedback Swap bookmark with reblog action Download latest nightly release Load remote profile follows and followers @@ -83,6 +84,7 @@ Replies will be opted out of discovery features Show how many people interacted with a post in the timeline Swipe to change viewed timeline + Vibrate on boost/favourite/bookmark Bookmark or reblog posts from the notification