From 0e6828fae1fb3f22553aedf0845005169046ddc5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Sch=C3=A4ttgen?= Date: Mon, 25 Mar 2019 21:32:29 +0100 Subject: [PATCH] Add ability to tap to reveal codes :eyes: --- .../beemdevelopment/aegis/Preferences.java | 4 ++ .../aegis/ui/MainActivity.java | 1 + .../aegis/ui/PreferencesFragment.java | 8 ++++ .../aegis/ui/views/EntryAdapter.java | 25 ++++++++--- .../aegis/ui/views/EntryHolder.java | 45 +++++++++++++++++-- .../aegis/ui/views/EntryListView.java | 4 ++ app/src/main/res/values/strings.xml | 3 ++ app/src/main/res/xml/preferences.xml | 6 +++ 8 files changed, 86 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/com/beemdevelopment/aegis/Preferences.java b/app/src/main/java/com/beemdevelopment/aegis/Preferences.java index e514d78f..22f54e2c 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/Preferences.java +++ b/app/src/main/java/com/beemdevelopment/aegis/Preferences.java @@ -15,6 +15,10 @@ public class Preferences { return _prefs.getBoolean("pref_dark_mode", false); } + public boolean isTapToRevealEnabled() { + return _prefs.getBoolean("pref_tap_to_reveal", false); + } + public boolean isSecureScreenEnabled() { return _prefs.getBoolean("pref_secure_screen", true); } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index 5a23cf6b..dea89344 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -67,6 +67,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene _entryListView = (EntryListView) getSupportFragmentManager().findFragmentById(R.id.key_profiles); _entryListView.setListener(this); _entryListView.setShowAccountName(getPreferences().isAccountNameVisible()); + _entryListView.setTapToReveal(getPreferences().isTapToRevealEnabled()); // set up the floating action button _fabMenu = findViewById(R.id.fab); diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java index a6b05454..fc25e2eb 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/PreferencesFragment.java @@ -142,6 +142,12 @@ public class PreferencesFragment extends PreferenceFragmentCompat { } }); + Preference tapToRevealPreference = findPreference("pref_tap_to_reveal"); + tapToRevealPreference.setOnPreferenceChangeListener((preference, newValue) -> { + _result.putExtra("needsRefresh", true); + return true; + }); + Preference screenPreference = findPreference("pref_secure_screen"); screenPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override @@ -157,6 +163,8 @@ public class PreferencesFragment extends PreferenceFragmentCompat { } }); + + _encryptionPreference = (SwitchPreference) findPreference("pref_encryption"); _encryptionPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { @Override diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java index 31b2e3ae..656eea45 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryAdapter.java @@ -24,6 +24,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I private List _shownEntries; private static Listener _listener; private boolean _showAccountName; + private boolean _tapToReveal; private String _groupFilter; // keeps track of the viewholders that are currently bound @@ -40,6 +41,10 @@ public class EntryAdapter extends RecyclerView.Adapter implements I _showAccountName = showAccountName; } + public void setTapToReveal(boolean tapToReveal) { + _tapToReveal = tapToReveal; + } + public void addEntry(DatabaseEntry entry) { _entries.add(entry); if (!isEntryFiltered(entry)) { @@ -121,11 +126,13 @@ public class EntryAdapter extends RecyclerView.Adapter implements I } public void refresh(boolean hard) { - if (hard) { - notifyDataSetChanged(); - } else { - for (EntryHolder holder : _holders) { - holder.refreshCode(); + if (!_tapToReveal) { + if (hard) { + notifyDataSetChanged(); + } else { + for (EntryHolder holder : _holders) { + holder.refreshCode(); + } } } } @@ -188,7 +195,7 @@ public class EntryAdapter extends RecyclerView.Adapter implements I public void onBindViewHolder(final EntryHolder holder, int position) { DatabaseEntry entry = _shownEntries.get(position); boolean showProgress = !isPeriodUniform() && entry.getInfo() instanceof TotpInfo; - holder.setData(entry, _showAccountName, showProgress); + holder.setData(entry, _showAccountName, showProgress, _tapToReveal); if (showProgress) { holder.startRefreshLoop(); } @@ -197,7 +204,11 @@ public class EntryAdapter extends RecyclerView.Adapter implements I @Override public void onClick(View v) { int position = holder.getAdapterPosition(); - _listener.onEntryClick(_shownEntries.get(position)); + if (_tapToReveal && !holder.codeIsRevealed()) { + holder.revealCode(); + } else { + _listener.onEntryClick(_shownEntries.get(position)); + } } }); holder.itemView.setOnLongClickListener(new View.OnLongClickListener() { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java index 6212ba5c..920bc194 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryHolder.java @@ -17,6 +17,7 @@ import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.db.DatabaseEntry; +import android.os.Handler; public class EntryHolder extends RecyclerView.ViewHolder { private TextView _profileName; @@ -26,12 +27,20 @@ public class EntryHolder extends RecyclerView.ViewHolder { private DatabaseEntry _entry; private ImageView _buttonRefresh; + private View _currentView; + + private boolean _codeIsRevealed; + private boolean _tapToReveal; + private PeriodProgressBar _progressBar; private UiRefresher _refresher; + private Handler _hiddenHandler; public EntryHolder(final View view) { super(view); + _currentView = view; + _profileName = view.findViewById(R.id.profile_account_name); _profileCode = view.findViewById(R.id.profile_code); _profileIssuer = view.findViewById(R.id.profile_issuer); @@ -45,7 +54,10 @@ public class EntryHolder extends RecyclerView.ViewHolder { _refresher = new UiRefresher(new UiRefresher.Listener() { @Override public void onRefresh() { - refreshCode(); + if (!_tapToReveal) { + refreshCode(); + } + _progressBar.refresh(); } @@ -54,10 +66,13 @@ public class EntryHolder extends RecyclerView.ViewHolder { return ((TotpInfo)_entry.getInfo()).getMillisTillNextRotation(); } }); + + _hiddenHandler = new Handler(); } - public void setData(DatabaseEntry entry, boolean showAccountName, boolean showProgress) { + public void setData(DatabaseEntry entry, boolean showAccountName, boolean showProgress, boolean tapToReveal) { _entry = entry; + _tapToReveal = tapToReveal; // only show the progress bar if there is no uniform period and the entry type is TotpInfo _progressBar.setVisibility(showProgress ? View.VISIBLE : View.GONE); @@ -83,7 +98,11 @@ public class EntryHolder extends RecyclerView.ViewHolder { _profileDrawable.setImageDrawable(drawable); } - refreshCode(); + if (tapToReveal) { + _profileCode.setText(_currentView.getContext().getResources().getString(R.string.tap_to_reveal)); + } else { + refreshCode(); + } } public void setOnRefreshClickListener(View.OnClickListener listener) { @@ -99,7 +118,27 @@ public class EntryHolder extends RecyclerView.ViewHolder { } public void refreshCode() { + updateCode(); + _codeIsRevealed = true; + } + + public void revealCode() { + updateCode(); + _hiddenHandler.postDelayed(this::hideCode, 30000); + _codeIsRevealed = true; + } + + private void updateCode() { String otp = _entry.getInfo().getOtp(); _profileCode.setText(otp.substring(0, otp.length() / 2) + " " + otp.substring(otp.length() / 2)); } + + public void hideCode() { + _profileCode.setText(_currentView.getContext().getResources().getString(R.string.tap_to_reveal)); + _codeIsRevealed = false; + } + + public boolean codeIsRevealed() { + return _codeIsRevealed; + } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java index 2e314644..94ff77e9 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/views/EntryListView.java @@ -151,6 +151,10 @@ public class EntryListView extends Fragment implements EntryAdapter.Listener { _adapter.setShowAccountName(showAccountName); } + public void setTapToReveal(boolean tapToReveal) { + _adapter.setTapToReveal(tapToReveal); + } + public void addEntry(DatabaseEntry entry) { _adapter.addEntry(entry); checkPeriodUniformity(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2f34d542..2252f05a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -27,6 +27,8 @@ Export the database Screen security Block screenshots and other attempts to capture the screen within the app + Tap to reveal + Tokens will be hidden by default. Tap on the tokens to reveal code. Encryption Encrypt the database and unlock it with a password or fingerprint Fingerprint @@ -150,4 +152,5 @@ Group name Edit groups Manage and delete your groups here + Hidden diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index 84c140ce..33dc4100 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -37,6 +37,12 @@ android:title="@string/pref_secure_screen_title" android:summary="@string/pref_secure_screen_summary" app:iconSpaceReserved="false"/> +