mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-04-22 14:59:14 +00:00
Add haptic feedback toggle for code refresh
This commit is contained in:
parent
9ab949a59e
commit
719787806c
9 changed files with 97 additions and 3 deletions
|
@ -4,6 +4,7 @@
|
|||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
<!-- NOTE: Disabled for now. See issue: #1047
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
|
|
@ -90,6 +90,10 @@ public class Preferences {
|
|||
return _prefs.getBoolean("pref_highlight_entry", false);
|
||||
}
|
||||
|
||||
public boolean isHapticFeedbackEnabled() {
|
||||
return _prefs.getBoolean("pref_haptic_feedback", true);
|
||||
}
|
||||
|
||||
public boolean isPauseFocusedEnabled() {
|
||||
boolean dependenciesEnabled = isTapToRevealEnabled() || isEntryHighlightEnabled();
|
||||
if (!dependenciesEnabled) return false;
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package com.beemdevelopment.aegis;
|
||||
|
||||
public class VibrationPatterns {
|
||||
private VibrationPatterns() {}
|
||||
|
||||
public static final long[] EXPIRING = {475, 20, 5, 20, 965, 20, 5, 20, 965, 20, 5, 20, 420};
|
||||
public static final long[] REFRESH_CODE = {0, 100};
|
||||
}
|
|
@ -23,7 +23,6 @@ public class UiRefresher {
|
|||
}
|
||||
_running = true;
|
||||
|
||||
_listener.onRefresh();
|
||||
_handler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.beemdevelopment.aegis.helpers;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.os.VibratorManager;
|
||||
|
||||
import com.beemdevelopment.aegis.Preferences;
|
||||
|
||||
import dagger.hilt.InstallIn;
|
||||
import dagger.hilt.android.EarlyEntryPoint;
|
||||
import dagger.hilt.android.EarlyEntryPoints;
|
||||
import dagger.hilt.components.SingletonComponent;
|
||||
|
||||
public class VibrationHelper {
|
||||
public static void vibratePattern(Context context, long[] pattern) {
|
||||
if (!isHapticFeedbackEnabled(context)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
VibratorManager vibratorManager = (VibratorManager) context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE);
|
||||
if (vibratorManager != null) {
|
||||
Vibrator vibrator = vibratorManager.getDefaultVibrator();
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
|
||||
vibrator.vibrate(effect);
|
||||
}
|
||||
} else {
|
||||
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||
if (vibrator != null) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
VibrationEffect effect = VibrationEffect.createWaveform(pattern, -1);
|
||||
vibrator.vibrate(effect);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isHapticFeedbackEnabled(Context context) {
|
||||
Preferences _prefs = EarlyEntryPoints.get(context.getApplicationContext(), PrefEntryPoint.class).getPreferences();
|
||||
|
||||
return _prefs.isHapticFeedbackEnabled();
|
||||
}
|
||||
|
||||
@EarlyEntryPoint
|
||||
@InstallIn(SingletonComponent.class)
|
||||
public interface PrefEntryPoint {
|
||||
Preferences getPreferences();
|
||||
}
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
package com.beemdevelopment.aegis.ui.views;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ObjectAnimator;
|
||||
|
@ -25,11 +27,13 @@ import androidx.recyclerview.widget.RecyclerView;
|
|||
import com.beemdevelopment.aegis.AccountNamePosition;
|
||||
import com.beemdevelopment.aegis.Preferences;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.VibrationPatterns;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
|
||||
import com.beemdevelopment.aegis.helpers.CenterVerticalSpan;
|
||||
import com.beemdevelopment.aegis.helpers.SimpleAnimationEndListener;
|
||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
||||
import com.beemdevelopment.aegis.helpers.VibrationHelper;
|
||||
import com.beemdevelopment.aegis.otp.HotpInfo;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfo;
|
||||
import com.beemdevelopment.aegis.otp.OtpInfoException;
|
||||
|
@ -67,6 +71,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
|
||||
private boolean _hidden;
|
||||
private boolean _paused;
|
||||
private boolean _nonUniform;
|
||||
|
||||
private TotpProgressBar _progressBar;
|
||||
private MaterialCardView _view;
|
||||
|
@ -118,12 +123,13 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
});
|
||||
}
|
||||
|
||||
public void setData(VaultEntry entry, Preferences.CodeGrouping groupSize, ViewMode viewMode, AccountNamePosition accountNamePosition, boolean showIcon, boolean showProgress, boolean hidden, boolean paused, boolean dimmed, boolean showExpirationState, boolean showNextCode) {
|
||||
public void setData(VaultEntry entry, Preferences.CodeGrouping groupSize, ViewMode viewMode, AccountNamePosition accountNamePosition, boolean showIcon, boolean nonUniform, boolean hidden, boolean paused, boolean dimmed, boolean showExpirationState, boolean showNextCode) {
|
||||
_entry = entry;
|
||||
_hidden = hidden;
|
||||
_paused = paused;
|
||||
_codeGrouping = groupSize;
|
||||
_viewMode = viewMode;
|
||||
_nonUniform = nonUniform;
|
||||
|
||||
_accountNamePosition = accountNamePosition;
|
||||
if (viewMode.equals(ViewMode.TILES) && _accountNamePosition == AccountNamePosition.END) {
|
||||
|
@ -140,7 +146,7 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
_favoriteIndicator.setVisibility(_entry.isFavorite() ? View.VISIBLE : View.INVISIBLE);
|
||||
|
||||
// only show the progress bar if there is no uniform period and the entry type is TotpInfo
|
||||
setShowProgress(showProgress);
|
||||
setShowProgress(nonUniform);
|
||||
|
||||
// only show the button if this entry is of type HotpInfo
|
||||
_buttonRefresh.setVisibility(entry.getInfo() instanceof HotpInfo ? View.VISIBLE : View.GONE);
|
||||
|
@ -457,6 +463,16 @@ public class EntryHolder extends RecyclerView.ViewHolder {
|
|||
final int blinkDuration = 3000;
|
||||
ValueAnimator delayAnim2 = ValueAnimator.ofFloat(0f, 0f);
|
||||
delayAnim2.setDuration((long) ((totalStateDuration - blinkDuration) / durationScale));
|
||||
delayAnim2.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (!_nonUniform) {
|
||||
if (itemView.isShown()) {
|
||||
VibrationHelper.vibratePattern(itemView.getContext(), VibrationPatterns.EXPIRING);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(_profileCode, "alpha", 1f, .5f);
|
||||
alphaAnim.setDuration((long) (500 / durationScale));
|
||||
|
|
|
@ -33,11 +33,13 @@ import com.beemdevelopment.aegis.CopyBehavior;
|
|||
import com.beemdevelopment.aegis.Preferences;
|
||||
import com.beemdevelopment.aegis.R;
|
||||
import com.beemdevelopment.aegis.SortCategory;
|
||||
import com.beemdevelopment.aegis.VibrationPatterns;
|
||||
import com.beemdevelopment.aegis.ViewMode;
|
||||
import com.beemdevelopment.aegis.helpers.AnimationsHelper;
|
||||
import com.beemdevelopment.aegis.helpers.MetricsHelper;
|
||||
import com.beemdevelopment.aegis.helpers.SimpleItemTouchHelperCallback;
|
||||
import com.beemdevelopment.aegis.helpers.UiRefresher;
|
||||
import com.beemdevelopment.aegis.helpers.VibrationHelper;
|
||||
import com.beemdevelopment.aegis.otp.TotpInfo;
|
||||
import com.beemdevelopment.aegis.ui.glide.GlideHelper;
|
||||
import com.beemdevelopment.aegis.ui.models.ErrorCardInfo;
|
||||
|
@ -144,6 +146,10 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener {
|
|||
@Override
|
||||
public void onRefresh() {
|
||||
refresh(false);
|
||||
|
||||
if (_recyclerView.isShown()) {
|
||||
VibrationHelper.vibratePattern(getContext(), VibrationPatterns.REFRESH_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -373,6 +373,8 @@
|
|||
<string name="note" comment="Users can add a note to an entry">Note</string>
|
||||
<string name="clear">Clear</string>
|
||||
|
||||
<string name="pref_haptic_feedback_summary">Make your device vibrate when codes are refreshing</string>
|
||||
<string name="pref_haptic_feedback_title">Haptic feedback</string>
|
||||
<string name="pref_highlight_entry_title">Highlight tokens when tapped</string>
|
||||
<string name="pref_highlight_entry_summary">Make tokens easier to distinguish from each other by temporarily highlighting them when tapped</string>
|
||||
<string name="pref_minimize_on_copy_title">Minimize on copy</string>
|
||||
|
|
|
@ -26,6 +26,13 @@
|
|||
android:title="@string/pref_copy_behavior_title"
|
||||
app:iconSpaceReserved="false"/>
|
||||
|
||||
<androidx.preference.SwitchPreferenceCompat
|
||||
android:defaultValue="true"
|
||||
android:key="pref_haptic_feedback"
|
||||
android:title="@string/pref_haptic_feedback_title"
|
||||
android:summary="@string/pref_haptic_feedback_summary"
|
||||
app:iconSpaceReserved="false"/>
|
||||
|
||||
<androidx.preference.SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="pref_highlight_entry"
|
||||
|
|
Loading…
Add table
Reference in a new issue